Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | merge latest change from trunk. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | no_ssh_sync_ip_resolve |
| Files: | files | file ages | folders |
| SHA3-256: |
5d5911e6fd0407d91861a8a02ab98db3 |
| User & Date: | mgagnon 2023-01-11 03:06:18.270 |
Context
|
2023-01-13
| ||
| 14:34 | Use the hostname as the report IP when doing SSH synchronization. ... (check-in: 0b7af9d865 user: drh tags: trunk) | |
|
2023-01-11
| ||
| 03:06 | merge latest change from trunk. ... (Closed-Leaf check-in: 5d5911e6fd user: mgagnon tags: no_ssh_sync_ip_resolve) | |
| 02:51 | Make proxy setting "system" by default to use http_proxy environment variable. Closer to old behavior and conform with most programs on Unix-like system. ... (check-in: 8f9f2cb7cd user: mgagnon tags: trunk) | |
|
2023-01-06
| ||
| 21:33 | Do not try to resolve the IP from the hostname when syncing using ssh:// protocol. Ssh may use the provided name as an alias defined in ~/.ssh/config which may not be resolvable or even resolve to an unrelated ip. This change can potentially avoid long timeout during name resolution failure. Equivalent to [52f08008e2790a81]. ... (check-in: e5c5622d4b user: mgagnon tags: no_ssh_sync_ip_resolve) | |
Changes
Changes to src/add.c.
| ︙ | ︙ | |||
360 361 362 363 364 365 366 | ** using the -f|--force option. ** ** The --case-sensitive option determines whether or not filenames should ** be treated case sensitive or not. If the option is not given, the default ** depends on the global setting, or the operating system default, if not set. ** ** Options: | < | 360 361 362 363 364 365 366 367 368 369 370 371 372 373 |
** using the -f|--force option.
**
** The --case-sensitive option determines whether or not filenames should
** be treated case sensitive or not. If the option is not given, the default
** depends on the global setting, or the operating system default, if not set.
**
** Options:
** --case-sensitive BOOL Override the case-sensitive setting
** --dotfiles Include files beginning with a dot (".")
** -f|--force Add files without prompting
** --ignore CSG Ignore unmanaged files matching patterns from
** the Comma Separated Glob (CSG) pattern list
** --clean CSG Also ignore files matching patterns from
** the Comma Separated Glob (CSG) list
|
| ︙ | ︙ |
Changes to src/alerts.c.
| ︙ | ︙ | |||
1125 1126 1127 1128 1129 1130 1131 | ** in the repository. This erases all subscription ** information. ** Use with extreme care ** ** ** send Compose and send pending email alerts. ** Some installations may want to do this via ** a cron-job to make sure alerts are sent ** in a timely manner. | < > | > | 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 | ** in the repository. This erases all subscription ** information. ** Use with extreme care ** ** ** send Compose and send pending email alerts. ** Some installations may want to do this via ** a cron-job to make sure alerts are sent ** in a timely manner. ** ** Options: ** --digest Send digests ** --renewal Send subscription renewal ** notices ** --test Write to standard output ** ** settings [NAME VALUE] With no arguments, list all email settings. ** Or change the value of a single email setting. ** ** status Report on the status of the email alert ** subsystem ** ** subscribers [PATTERN] List all subscribers matching PATTERN. Either ** LIKE or GLOB wildcards can be used in PATTERN. ** ** test-message TO [OPTS] Send a single email message using whatever ** email sending mechanism is currently configured. ** Use this for testing the email notification ** configuration. ** ** Options: ** --body FILENAME Content from FILENAME ** --smtp-trace Trace SMTP processing ** --stdout Send msg to stdout ** -S|--subject SUBJECT Message "subject:" ** ** unsubscribe EMAIL Remove a single subscriber with the given EMAIL. */ |
| ︙ | ︙ | |||
2706 2707 2708 2709 2710 2711 2712 | ** ** EVENTIDs are text. The first character is 'c', 'f', 't', or 'w' ** for check-in, forum, ticket, or wiki. The remaining text is a ** integer that references the EVENT.OBJID value for the event. ** Run /timeline?showid to see these OBJID values. ** ** Options: | < | 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 |
**
** EVENTIDs are text. The first character is 'c', 'f', 't', or 'w'
** for check-in, forum, ticket, or wiki. The remaining text is a
** integer that references the EVENT.OBJID value for the event.
** Run /timeline?showid to see these OBJID values.
**
** Options:
** --digest Generate digest alert text
** --needmod Assume all events are pending moderator approval
*/
void test_alert_cmd(void){
Blob out;
int nEvent;
int needMod;
|
| ︙ | ︙ | |||
2767 2768 2769 2770 2771 2772 2773 | ** ** EVENTIDs are text. The first character is 'c', 'f', 't', or 'w' ** for check-in, forum, ticket, or wiki. The remaining text is a ** integer that references the EVENT.OBJID value for the event. ** Run /timeline?showid to see these OBJID values. ** ** Options: | < < < | 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 |
**
** EVENTIDs are text. The first character is 'c', 'f', 't', or 'w'
** for check-in, forum, ticket, or wiki. The remaining text is a
** integer that references the EVENT.OBJID value for the event.
** Run /timeline?showid to see these OBJID values.
**
** Options:
** --backoffice Run alert_backoffice() after all alerts have
** been added. This will cause the alerts to be
** sent out with the SENDALERT_TRACE option.
** --debug Like --backoffice, but add the SENDALERT_STDOUT
** so that emails are printed to standard output
** rather than being sent.
** --digest Process emails using SENDALERT_DIGEST
*/
void test_add_alert_cmd(void){
int i;
int doAuto = find_option("backoffice",0,0)!=0;
unsigned mFlags = 0;
if( find_option("debug",0,0)!=0 ){
|
| ︙ | ︙ |
Changes to src/attach.c.
| ︙ | ︙ | |||
676 677 678 679 680 681 682 | /* ** COMMAND: attachment* ** ** Usage: %fossil attachment add ?PAGENAME? FILENAME ?OPTIONS? ** ** Add an attachment to an existing wiki page or tech note. | < > < | | 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | /* ** COMMAND: attachment* ** ** Usage: %fossil attachment add ?PAGENAME? FILENAME ?OPTIONS? ** ** Add an attachment to an existing wiki page or tech note. ** ** Options: ** -t|--technote DATETIME Specifies the timestamp of ** the technote to which the attachment ** is to be made. The attachment will be ** to the most recently modified tech note ** with the specified timestamp. ** -t|--technote TECHNOTE-ID Specifies the technote to be ** updated by its technote id ** ** One of PAGENAME, DATETIME or TECHNOTE-ID must be specified. ** ** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in ** year-month-day form, it may be truncated, the "T" may be replaced by ** a space, and it may also name a timezone offset from UTC as "-HH:MM" ** (westward) or "+HH:MM" (eastward). Either no timezone suffix or "Z" |
| ︙ | ︙ | |||
790 791 792 793 794 795 796 | ** ** List attachments for one or more attachment targets. The target ** name arguments are glob prefixes for the attachment.target ** field. If no names are provided then a prefix of [a-zA-Z] is used, ** which will match most wiki page names and some ticket hashes. ** ** Options: | < | | 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 |
**
** List attachments for one or more attachment targets. The target
** name arguments are glob prefixes for the attachment.target
** field. If no names are provided then a prefix of [a-zA-Z] is used,
** which will match most wiki page names and some ticket hashes.
**
** Options:
** -latest List only the latest version of a given attachment
**
*/
void test_list_attachments(void){
Stmt q;
int i;
const int fLatest = find_option("latest", 0, 0) != 0;
|
| ︙ | ︙ |
Changes to src/backlink.c.
| ︙ | ︙ | |||
356 357 358 359 360 361 362 | ** Read the content of INPUT-FILE and pass it into the backlink_extract() ** routine. But instead of adding backlinks to the backlink table, ** just print them on stdout. SRCID and SRCTYPE are integers. ** ** Options: ** --mtime DATETIME Use an alternative date/time. Defaults to the ** current date/time. | | | 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 |
** Read the content of INPUT-FILE and pass it into the backlink_extract()
** routine. But instead of adding backlinks to the backlink table,
** just print them on stdout. SRCID and SRCTYPE are integers.
**
** Options:
** --mtime DATETIME Use an alternative date/time. Defaults to the
** current date/time.
** --mimetype TYPE Use an alternative mimetype
*/
void test_backlinks_cmd(void){
const char *zMTime = find_option("mtime",0,1);
const char *zMimetype = find_option("mimetype",0,1);
const int mimetype = parse_mimetype(zMimetype);
Blob in;
int srcid;
|
| ︙ | ︙ |
Changes to src/bisect.c.
| ︙ | ︙ | |||
384 385 386 387 388 389 390 | ); } /* ** fossil bisect run [OPTIONS] COMMAND ** ** Invoke COMMAND (with arguments) repeatedly to perform the bisect. | < > | 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
);
}
/*
** fossil bisect run [OPTIONS] COMMAND
**
** Invoke COMMAND (with arguments) repeatedly to perform the bisect.
**
** Options:
** -i|--interactive Prompt user for decisions rather than
** using the return code from COMMAND
*/
static void bisect_run(void){
const char *zCmd;
int isInteractive = 0;
int i;
|
| ︙ | ︙ | |||
505 506 507 508 509 510 511 | ** Reinitialize a bisect session. This cancels prior bisect history ** and allows a bisect session to start over from the beginning. ** ** > fossil bisect run [OPTIONS] COMMAND ** ** Invoke COMMAND repeatedly to run the bisect. The exit code for ** COMMAND should be 0 for "good", 125 for "skip", and any other value | | > | 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 | ** Reinitialize a bisect session. This cancels prior bisect history ** and allows a bisect session to start over from the beginning. ** ** > fossil bisect run [OPTIONS] COMMAND ** ** Invoke COMMAND repeatedly to run the bisect. The exit code for ** COMMAND should be 0 for "good", 125 for "skip", and any other value ** for "bad". ** ** Options: ** -i|--interactive Prompt the user for the good/bad/skip decision ** after each step, rather than using the exit ** code from COMMAND ** ** > fossil bisect skip ?VERSION? ** ** Cause VERSION (or the current check-out if VERSION is omitted) to |
| ︙ | ︙ |
Changes to src/blob.c.
| ︙ | ︙ | |||
122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
/*
** Other replacements for ctype.h functions.
*/
int fossil_islower(char c){ return c>='a' && c<='z'; }
int fossil_isupper(char c){ return c>='A' && c<='Z'; }
int fossil_isdigit(char c){ return c>='0' && c<='9'; }
int fossil_tolower(char c){
return fossil_isupper(c) ? c - 'A' + 'a' : c;
}
int fossil_toupper(char c){
return fossil_islower(c) ? c - 'a' + 'A' : c;
}
int fossil_isalpha(char c){
| > | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
/*
** Other replacements for ctype.h functions.
*/
int fossil_islower(char c){ return c>='a' && c<='z'; }
int fossil_isupper(char c){ return c>='A' && c<='Z'; }
int fossil_isdigit(char c){ return c>='0' && c<='9'; }
int fossil_isxdigit(char c){ return (c>='0' && c<='9') || (c>='a' && c<='f'); }
int fossil_tolower(char c){
return fossil_isupper(c) ? c - 'A' + 'a' : c;
}
int fossil_toupper(char c){
return fossil_islower(c) ? c - 'a' + 'A' : c;
}
int fossil_isalpha(char c){
|
| ︙ | ︙ |
Changes to src/branch.c.
| ︙ | ︙ | |||
584 585 586 587 588 589 590 | ** of the repository identified by the -R or --repository option. ** ** > fossil branch close|reopen ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES? ** ** Adds or cancels the "closed" tag to one or more branches. ** It accepts arbitrary unambiguous symbolic names but ** will only resolve check-in names and skips any which resolve | | > > | | | > > | | > | | | | | < | 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 |
** of the repository identified by the -R or --repository option.
**
** > fossil branch close|reopen ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
**
** Adds or cancels the "closed" tag to one or more branches.
** It accepts arbitrary unambiguous symbolic names but
** will only resolve check-in names and skips any which resolve
** to non-leaf check-ins.
**
** Options:
** -n|--dry-run Do not commit changes, but dump artifact
** to stdout
** -v|--verbose Output more information
** --date-override DATE DATE to use instead of 'now'
** --user-override USER USER to use instead of the current default
**
** > fossil branch current
**
** Print the name of the branch for the current check-out
**
** > fossil branch hide|unhide ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
**
** Adds or cancels the "hidden" tag for the specified branches or
** or check-in IDs. Accepts the same options as the close
** subcommand.
**
** > fossil branch info BRANCH-NAME
**
** Print information about a branch
**
** > fossil branch list|ls ?OPTIONS? ?GLOB?
** > fossil branch lsh ?OPTIONS? ?LIMIT?
**
** List all branches.
**
** Options:
** -a|--all List all branches. Default show only open branches
** -c|--closed List closed branches
** -p List only private branches
** -r Reverse the sort order
** -t Show recently changed branches first
**
** The current branch is marked with an asterisk. Private branches are
** marked with a hash sign.
**
** If GLOB is given, show only branches matching the pattern.
**
** The "lsh" variant of this subcommand shows recently changed branches,
** and accepts an optional LIMIT argument (defaults to 5) to cap output,
** but no GLOB argument. All other options are supported, with -t being
** an implied no-op.
**
** > fossil branch new BRANCH-NAME BASIS ?OPTIONS?
**
** Create a new branch BRANCH-NAME off of check-in BASIS.
**
** Options:
** --private Branch is private (i.e., remains local)
** --bgcolor COLOR Use COLOR instead of automatic background
** ("auto" lets Fossil choose it automatically,
** even for private branches)
** --nosign Do not sign contents on this branch
** --date-override DATE DATE to use instead of 'now'
** --user-override USER USER to use instead of the current default
**
** DATE may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
** year-month-day form, it may be truncated, the "T" may be
** replaced by a space, and it may also name a timezone offset
** from UTC as "-HH:MM" (westward) or "+HH:MM" (eastward).
** Either no timezone suffix or "Z" means UTC.
**
** Options:
** -R|--repository REPO Run commands on repository REPO
*/
void branch_cmd(void){
int n;
const char *zCmd = "list";
db_find_and_open_repository(0, 0);
if( g.argc>=3 ) zCmd = g.argv[2];
|
| ︙ | ︙ |
Changes to src/checkout.c.
| ︙ | ︙ | |||
395 396 397 398 399 400 401 | ** Usage: %fossil close ?OPTIONS? ** ** The opposite of "[[open]]". Close the current database connection. ** Require a -f or --force flag if there are unsaved changes in the ** current check-out or if there is non-empty stash. ** ** Options: | | | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 |
** Usage: %fossil close ?OPTIONS?
**
** The opposite of "[[open]]". Close the current database connection.
** Require a -f or --force flag if there are unsaved changes in the
** current check-out or if there is non-empty stash.
**
** Options:
** -f|--force Necessary to close a check-out with uncommitted changes
**
** See also: [[open]]
*/
void close_cmd(void){
int forceFlag = find_option("force","f",0)!=0;
db_must_be_within_tree();
|
| ︙ | ︙ |
Changes to src/clone.c.
| ︙ | ︙ | |||
128 129 130 131 132 133 134 | ** --nested Allow opening a repository inside an opened ** check-out ** --nocompress Omit extra delta compression ** --no-open Clone only. Do not open a check-out. ** --once Don't remember the URI. ** --private Also clone private branches ** --save-http-password Remember the HTTP password without asking | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | ** --nested Allow opening a repository inside an opened ** check-out ** --nocompress Omit extra delta compression ** --no-open Clone only. Do not open a check-out. ** --once Don't remember the URI. ** --private Also clone private branches ** --save-http-password Remember the HTTP password without asking ** -c|--ssh-command SSH Use SSH as the "ssh" command ** --ssl-identity FILENAME Use the SSL identity if requested by the server ** --transport-command CMD Use CMD to move messages to the server and back ** -u|--unversioned Also sync unversioned content ** -v|--verbose Show more statistics in output ** --workdir DIR Also open a check-out in DIR ** ** See also: [[init]], [[open]] |
| ︙ | ︙ |
Changes to src/comformat.c.
| ︙ | ︙ | |||
544 545 546 547 548 549 550 | ** ** Usage: %fossil test-comment-format ?OPTIONS? PREFIX TEXT ?ORIGTEXT? ** ** Test comment formatting and printing. Use for testing only. ** ** Options: ** --file The comment text is really just a file name to | | | | | | | | 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
**
** Usage: %fossil test-comment-format ?OPTIONS? PREFIX TEXT ?ORIGTEXT?
**
** Test comment formatting and printing. Use for testing only.
**
** Options:
** --file The comment text is really just a file name to
** read it from
** --decode Decode the text using the same method used when
** handling the value of a C-card from a manifest.
** --legacy Use the legacy comment printing algorithm
** --trimcrlf Enable trimming of leading/trailing CR/LF
** --trimspace Enable trimming of leading/trailing spaces
** --wordbreak Attempt to break lines on word boundaries
** --origbreak Attempt to break when the original comment text
** is detected
** --indent Number of spaces to indent (default (-1) is to
** auto-detect). Zero means no indent.
** -W|--width NUM Width of lines (default (-1) is to auto-detect).
** Zero means no limit.
*/
void test_comment_format(void){
const char *zWidth;
|
| ︙ | ︙ |
Changes to src/content.c.
| ︙ | ︙ | |||
955 956 957 958 959 960 961 | ** COMMAND: test-integrity ** ** Verify that all content can be extracted from the BLOB table correctly. ** If the BLOB table is correct, then the repository can always be ** successfully reconstructed using "fossil rebuild". ** ** Options: | < < < | 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 |
** COMMAND: test-integrity
**
** Verify that all content can be extracted from the BLOB table correctly.
** If the BLOB table is correct, then the repository can always be
** successfully reconstructed using "fossil rebuild".
**
** Options:
** -d|--db-only Run "PRAGMA integrity_check" on the database only.
** No other validation is performed.
** --parse Parse all manifests, wikis, tickets, events, and
** so forth, reporting any errors found.
** -q|--quick Run "PRAGMA quick_check" on the database only.
** No other validation is performed.
*/
void test_integrity(void){
Stmt q;
Blob content;
int n1 = 0;
|
| ︙ | ︙ | |||
1195 1196 1197 1198 1199 1200 1201 | ** Usage: %fossil test-missing ** ** Look at every artifact in the repository and verify that ** all references are satisfied. Report any referenced artifacts ** that are missing or shunned. ** ** Options: | < | 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 |
** Usage: %fossil test-missing
**
** Look at every artifact in the repository and verify that
** all references are satisfied. Report any referenced artifacts
** that are missing or shunned.
**
** Options:
** --notshunned Do not report shunned artifacts
** --quiet Only show output if there are errors
*/
void test_missing(void){
Stmt q;
Blob content;
int nErr = 0;
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
915 916 917 918 919 920 921 | } /* ** COMMAND: test-db-prepare ** Usage: %fossil test-db-prepare ?OPTIONS? SQL-STATEMENT ** ** Options: | < | | | 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 |
}
/*
** COMMAND: test-db-prepare
** Usage: %fossil test-db-prepare ?OPTIONS? SQL-STATEMENT
**
** Options:
** --auth-report Enable the ticket report query authorizer
** --auth-ticket Enable the ticket schema query authorizer
**
** Invoke db_prepare() on the SQL input. Report any errors encountered.
** This command is used to verify error detection logic in the db_prepare()
** utility routine.
*/
void db_test_db_prepare(void){
const int fAuthReport = find_option("auth-report",0,0)!=0;
|
| ︙ | ︙ | |||
4454 4455 4456 4457 4458 4459 4460 | */ /* ** SETTING: pgp-command width=40 sensitive ** Command used to clear-sign manifests at check-in. ** Default value is "gpg --clearsign -o" */ /* | | | | > | 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 | */ /* ** SETTING: pgp-command width=40 sensitive ** Command used to clear-sign manifests at check-in. ** Default value is "gpg --clearsign -o" */ /* ** SETTING: proxy width=32 default=system ** URL of the HTTP proxy. If undefined or "system", the "http_proxy" ** environment variable is consulted. If "off", a direct HTTP connection is ** used. */ /* ** SETTING: redirect-to-https default=0 width=-1 ** Specifies whether or not to redirect http:// requests to ** https:// URIs. A value of 0 (the default) means not to ** redirect, 1 means to redirect only the /login page, and 2 ** means to always redirect. |
| ︙ | ︙ | |||
4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 |
** for the repository list page. If none of the repositories on the list
** have a non-zero "repolist-skin" setting then the repository list is
** displayed using unadorned HTML ("skinless").
**
** If repolist-skin has a value of 2, then the repository is omitted from
** the list in use cases 1 through 4, but not for 5 and 6.
*/
/*
** SETTING: self-register boolean default=off sensitive
** Allow users to register themselves through the HTTP UI.
** This is useful if you want to see other names than
** "Anonymous" in e.g. ticketing system. On the other hand
** users can not be deleted.
*/
| > > > > > > > | 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 |
** for the repository list page. If none of the repositories on the list
** have a non-zero "repolist-skin" setting then the repository list is
** displayed using unadorned HTML ("skinless").
**
** If repolist-skin has a value of 2, then the repository is omitted from
** the list in use cases 1 through 4, but not for 5 and 6.
*/
/*
** SETTING: self-pw-reset boolean default=off sensitive
** Allow users to request that an email containing a hyperlink
** to the /resetpw page be sent to their email address of record,
** thus allowing forgetful users to reset their forgotten passwords
** without administrator involvement.
*/
/*
** SETTING: self-register boolean default=off sensitive
** Allow users to register themselves through the HTTP UI.
** This is useful if you want to see other names than
** "Anonymous" in e.g. ticketing system. On the other hand
** users can not be deleted.
*/
|
| ︙ | ︙ | |||
4692 4693 4694 4695 4696 4697 4698 | ** configuration database. If both a local and a global value exists for a ** setting, the local value takes precedence. This command normally operates ** on the local settings. Use the --global option to change global settings. ** ** Options: ** --global Set or unset the given property globally instead of ** setting or unsetting it for the open repository only | < | 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 |
** configuration database. If both a local and a global value exists for a
** setting, the local value takes precedence. This command normally operates
** on the local settings. Use the --global option to change global settings.
**
** Options:
** --global Set or unset the given property globally instead of
** setting or unsetting it for the open repository only
** --exact Only consider exact name matches
**
** See also: [[configuration]]
*/
void setting_cmd(void){
int i;
int globalFlag = find_option("global","g",0)!=0;
|
| ︙ | ︙ | |||
4846 4847 4848 4849 4850 4851 4852 | ** optimization. FILENAME can also be the configuration database file ** (~/.fossil or ~/.config/fossil.db) or a local .fslckout or _FOSSIL_ file. ** ** The purpose of this command is for testing the WITHOUT ROWID capabilities ** of SQLite. There is no big advantage to using WITHOUT ROWID in Fossil. ** ** Options: | | | 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 |
** optimization. FILENAME can also be the configuration database file
** (~/.fossil or ~/.config/fossil.db) or a local .fslckout or _FOSSIL_ file.
**
** The purpose of this command is for testing the WITHOUT ROWID capabilities
** of SQLite. There is no big advantage to using WITHOUT ROWID in Fossil.
**
** Options:
** -n|--dry-run No changes. Just print what would happen.
*/
void test_without_rowid(void){
int i, j;
Stmt q;
Blob allSql;
int dryRun = find_option("dry-run", "n", 0)!=0;
for(i=2; i<g.argc; i++){
|
| ︙ | ︙ |
Changes to src/diffcmd.c.
| ︙ | ︙ | |||
1040 1041 1042 1043 1044 1045 1046 | ** --tk Pop up a TCL/TK-based GUI to show the diff ** --by Show a side-by-side diff in the default web browser ** -b Show a linear diff in the default web browser ** -y Show a text side-by-side diff ** --webpage Format output as HTML ** --webpage -y HTML output in the side-by-side format ** | | | | | | 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 | ** --tk Pop up a TCL/TK-based GUI to show the diff ** --by Show a side-by-side diff in the default web browser ** -b Show a linear diff in the default web browser ** -y Show a text side-by-side diff ** --webpage Format output as HTML ** --webpage -y HTML output in the side-by-side format ** ** The "--from VERSION" option is used to specify the source check-in ** for the diff operation. If not specified, the source check-in is the ** base check-in for the current check-out. Similarly, the "--to VERSION" ** option specifies the check-in from which the second version of the file ** or files is taken. If there is no "--to" option then the (possibly edited) ** files in the current check-out are used. The "--checkin VERSION" option ** shows the changes made by check-in VERSION relative to its primary parent. ** The "--branch BRANCHNAME" shows all the changes on the branch BRANCHNAME. ** ** The "-i" command-line option forces the use of Fossil's own internal ** diff logic rather than any external diff program that might be configured ** using the "setting" command. If no external diff program is configured, ** then the "-i" option is a no-op. The "-i" option converts "gdiff" into ** "diff". ** ** The "--diff-binary" option enables or disables the inclusion of binary files ** when using an external diff program. ** ** The "--binary" option causes files matching the glob PATTERN to be treated ** as binary when considering if they should be used with the external diff ** program. This option overrides the "binary-glob" setting. ** ** These command show differences between managed files. Use the "fossil xdiff" ** command to see differences in unmanaged files. ** ** Options: ** --binary PATTERN Treat files that match the glob PATTERN ** as binary |
| ︙ | ︙ | |||
1083 1084 1085 1086 1087 1088 1089 | ** --exec-abs-paths Force absolute path names on external commands ** --exec-rel-paths Force relative path names on external commands ** -r|--from VERSION Select VERSION as source for the diff ** -w|--ignore-all-space Ignore white space when comparing lines ** -i|--internal Use internal diff logic ** --json Output formatted as JSON ** -N|--new-file Alias for --verbose | | | 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 | ** --exec-abs-paths Force absolute path names on external commands ** --exec-rel-paths Force relative path names on external commands ** -r|--from VERSION Select VERSION as source for the diff ** -w|--ignore-all-space Ignore white space when comparing lines ** -i|--internal Use internal diff logic ** --json Output formatted as JSON ** -N|--new-file Alias for --verbose ** --numstat Show only the number of added and deleted lines ** -y|--side-by-side Side-by-side diff ** --strip-trailing-cr Strip trailing CR ** --tcl TCL-formated output used internally by --tk ** --tclsh PATH TCL/TK used for --tk (default: "tclsh") ** --tk Launch a Tcl/Tk GUI for display ** --to VERSION Select VERSION as target for the diff ** --undo Diff against the "undo" buffer |
| ︙ | ︙ |
Changes to src/dispatch.c.
| ︙ | ︙ | |||
622 623 624 625 626 627 628 | ** Usage: %fossil test-all-help ?OPTIONS? ** ** Show help text for commands and pages. Useful for proof-reading. ** Defaults to just the CLI commands. Specify --www to see only the ** web pages, or --everything to see both commands and pages. ** ** Options: | | | | | | | | | 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 |
** Usage: %fossil test-all-help ?OPTIONS?
**
** Show help text for commands and pages. Useful for proof-reading.
** Defaults to just the CLI commands. Specify --www to see only the
** web pages, or --everything to see both commands and pages.
**
** Options:
** -a|--aliases Show aliases
** -e|--everything Show all commands and pages. Omit aliases to
** avoid duplicates.
** -h|--html Transform output to HTML
** -o|--options Show global options
** -r|--raw No output formatting
** -s|--settings Show settings
** -t|--test Include test- commands
** -w|--www Show WWW pages
*/
void test_all_help_cmd(void){
int mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER;
int useHtml = find_option("html","h",0)!=0;
int rawOut = find_option("raw","r",0)!=0;
if( find_option("www","w",0) ){
|
| ︙ | ︙ |
Changes to src/file.c.
| ︙ | ︙ | |||
1473 1474 1475 1476 1477 1478 1479 | ** ** Usage: %fossil test-file-environment FILENAME... ** ** Display the effective file handling subsystem "settings" and then ** display file system information about the files specified, if any. ** ** Options: | < | | | | 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 |
**
** Usage: %fossil test-file-environment FILENAME...
**
** Display the effective file handling subsystem "settings" and then
** display file system information about the files specified, if any.
**
** Options:
** --allow-symlinks BOOLEAN Temporarily turn allow-symlinks on/off
** --open-config Open the configuration database first
** --reset Reset cached stat() info for each file
** --root ROOT Use ROOT as the root of the check-out
** --slash Trailing slashes, if any, are retained
*/
void cmd_test_file_environment(void){
int i;
int slashFlag = find_option("slash",0,0)!=0;
int resetFlag = find_option("reset",0,0)!=0;
const char *zRoot = find_option("root",0,1);
const char *zAllow = find_option("allow-symlinks",0,1);
|
| ︙ | ︙ | |||
1772 1773 1774 1775 1776 1777 1778 | /* ** COMMAND: test-tree-name ** ** Test the operation of the tree name generator. ** ** Options: | | | 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 |
/*
** COMMAND: test-tree-name
**
** Test the operation of the tree name generator.
**
** Options:
** --absolute Return an absolute path instead of a relative one
** --case-sensitive B Enable or disable case-sensitive filenames. B is
** a boolean: "yes", "no", "true", "false", etc.
*/
void cmd_test_tree_name(void){
int i;
Blob x;
int absoluteFlag = find_option("absolute",0,0)!=0;
|
| ︙ | ︙ |
Changes to src/fileedit.c.
| ︙ | ︙ | |||
696 697 698 699 700 701 702 | ** ** Usage: %fossil test-ci-mini ?OPTIONS? FILENAME ** ** where FILENAME is a repo-relative name as it would appear in the ** vfile table. ** ** Options: | < | | | | | | | | | | | | | | 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 |
**
** Usage: %fossil test-ci-mini ?OPTIONS? FILENAME
**
** where FILENAME is a repo-relative name as it would appear in the
** vfile table.
**
** Options:
** -R|--repository REPO The repository file to commit to
** --as FILENAME The repository-side name of the input
** file, relative to the top of the
** repository. Default is the same as the
** input file name.
** -m|--comment COMMENT Required check-in comment
** -M|--comment-file FILE Reads check-in comment from the given file
** -r|--revision VERSION Commit from this version. Default is
** the check-out version (if available) or
** trunk (if used without a check-out).
** --allow-fork Allows the commit to be made against a
** non-leaf parent. Note that no autosync
** is performed beforehand.
** --allow-merge-conflict Allows check-in of a file even if it
** appears to contain a fossil merge conflict
** marker
** --user-override USER USER to use instead of the current
** default
** --date-override DATETIME DATE to use instead of 'now'
** --allow-older Allow a commit to be older than its
** ancestor
** --convert-eol-inherit Convert EOL style of the check-in to match
** the previous version's content
** --convert-eol-unix Convert the EOL style to Unix
** --convert-eol-windows Convert the EOL style to Windows.
** (Only one of the --convert-eol-X options may be used and they only
** modified the saved blob, not the input file.)
** --delta Prefer to generate a delta manifest, if
** able. The forbid-delta-manifests repo
** config option trumps this, as do certain
** heuristics.
** --allow-new-file Allow addition of a new file this way.
** Disabled by default to avoid that case-
** sensitivity errors inadvertently lead to
** adding a new file where an update is
** intended.
** -d|--dump-manifest Dumps the generated manifest to stdout
** immediately after it's generated
** --save-manifest FILE Saves the generated manifest to a file
** after successfully processing it
** --wet-run Disables the default dry-run mode
**
** Example:
**
** %fossil test-ci-mini -R REPO -m ... -r foo --as src/myfile.c myfile.c
**
*/
void test_ci_mini_cmd(void){
|
| ︙ | ︙ |
Changes to src/http.c.
| ︙ | ︙ | |||
559 560 561 562 563 564 565 | ** ** If a second filename (OUTPUT) is given after PAYLOAD, then the reply ** is written into that second file instead of being written on standard ** output. Use the "--out OUTPUT" option to specify an output file for ** a GET request where there is no PAYLOAD. ** ** Options: | < | 559 560 561 562 563 564 565 566 567 568 569 570 571 572 |
**
** If a second filename (OUTPUT) is given after PAYLOAD, then the reply
** is written into that second file instead of being written on standard
** output. Use the "--out OUTPUT" option to specify an output file for
** a GET request where there is no PAYLOAD.
**
** Options:
** --compress Use ZLIB compression on the payload
** --mimetype TYPE Mimetype of the payload
** --out FILE Store the reply in FILE
** -v Verbose output
** --xfer PAYLOAD in a Fossil xfer protocol message
*/
void test_httpmsg_command(void){
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
185 186 187 188 189 190 191 | ** to access the repository. The --verbose is (currently) a no-op if ** the argument is the name of an object within the repository. ** ** Use the "finfo" command to get information about a specific ** file in a check-out. ** ** Options: | < | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
** to access the repository. The --verbose is (currently) a no-op if
** the argument is the name of an object within the repository.
**
** Use the "finfo" command to get information about a specific
** file in a check-out.
**
** Options:
** -R|--repository REPO Extract info from repository REPO
** -v|--verbose Show extra information about repositories
**
** See also: [[annotate]], [[artifact]], [[finfo]], [[timeline]]
*/
void info_cmd(void){
i64 fsize;
|
| ︙ | ︙ | |||
3469 3470 3471 3472 3473 3474 3475 | ** COMMAND: amend ** ** Usage: %fossil amend HASH OPTION ?OPTION ...? ** ** Amend the tags on check-in HASH to change how it displays in the timeline. ** ** Options: | < | 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 | ** COMMAND: amend ** ** Usage: %fossil amend HASH OPTION ?OPTION ...? ** ** Amend the tags on check-in HASH to change how it displays in the timeline. ** ** Options: ** --author USER Make USER the author for check-in ** -m|--comment COMMENT Make COMMENT the check-in comment ** -M|--message-file FILE Read the amended comment from FILE ** -e|--edit-comment Launch editor to revise comment ** --date DATETIME Make DATETIME the check-in time ** --bgcolor COLOR Apply COLOR to this check-in ** --branchcolor COLOR Apply and propagate COLOR to the branch |
| ︙ | ︙ | |||
3811 3812 3813 3814 3815 3816 3817 | ** If no VERSION is provided, describe the currently checked-out version. ** ** If VERSION and the found ancestor refer to the same commit, the last two ** components are omitted, unless --long is provided. When no fitting tagged ** ancestor is found, show only the short hash of VERSION. ** ** Options: | < | 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 |
** If no VERSION is provided, describe the currently checked-out version.
**
** If VERSION and the found ancestor refer to the same commit, the last two
** components are omitted, unless --long is provided. When no fitting tagged
** ancestor is found, show only the short hash of VERSION.
**
** Options:
** --digits Display so many hex digits of the hash
** (default: the larger of 6 and the 'hash-digit' setting)
** -d|--dirty Show whether there are changes to be committed
** --long Always show all three components
** --match GLOB Consider only non-propagating tags matching GLOB
*/
void describe_cmd(void){
|
| ︙ | ︙ |
Changes to src/login.c.
| ︙ | ︙ | |||
508 509 510 511 512 513 514 515 516 517 518 519 520 521 |
int rc;
if( zReferer==0 ) return 0;
zPattern = mprintf("%s/login*", g.zBaseURL);
rc = sqlite3_strglob(zPattern, zReferer)==0;
fossil_free(zPattern);
return rc;
}
/*
** Return TRUE if self-registration is available. If the zNeeded
** argument is not NULL, then only return true if self-registration is
** available and any of the capabilities named in zNeeded are available
** to self-registered users.
*/
| > > > > > > > > > | 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 |
int rc;
if( zReferer==0 ) return 0;
zPattern = mprintf("%s/login*", g.zBaseURL);
rc = sqlite3_strglob(zPattern, zReferer)==0;
fossil_free(zPattern);
return rc;
}
/*
** Return true if users are allowed to reset their own passwords.
*/
int login_self_password_reset_available(void){
if( !db_get_boolean("self-pw-reset",0) ) return 0;
if( !alert_tables_exist() ) return 0;
return 1;
}
/*
** Return TRUE if self-registration is available. If the zNeeded
** argument is not NULL, then only return true if self-registration is
** available and any of the capabilities named in zNeeded are available
** to self-registered users.
*/
|
| ︙ | ︙ | |||
558 559 560 561 562 563 564 565 566 567 568 569 570 571 |
char *zSha1Pw;
const char *zIpAddr; /* IP address of requestor */
const int noAnon = P("noanon")!=0;
int rememberMe; /* If true, use persistent cookie, else
session cookie. Toggled per
checkbox. */
login_check_credentials();
fossil_redirect_to_https_if_needed(1);
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
constant_time_cmp_function, 0, 0);
zUsername = P("u");
zPasswd = P("p");
anonFlag = g.zLogin==0 && PB("anon");
| > > > > > > | 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 |
char *zSha1Pw;
const char *zIpAddr; /* IP address of requestor */
const int noAnon = P("noanon")!=0;
int rememberMe; /* If true, use persistent cookie, else
session cookie. Toggled per
checkbox. */
if( P("pwreset")!=0 && login_self_password_reset_available() ){
/* If the "Reset Password" button in the form was pressed, render
** the Request Password Reset page in place of this one. */
login_reqpwreset_page();
return;
}
login_check_credentials();
fossil_redirect_to_https_if_needed(1);
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
constant_time_cmp_function, 0, 0);
zUsername = P("u");
zPasswd = P("p");
anonFlag = g.zLogin==0 && PB("anon");
|
| ︙ | ︙ | |||
611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 |
;
}else{
char *zNewPw = sha1_shared_secret(zNew1, g.zLogin, 0);
char *zChngPw;
char *zErr;
int rc;
db_unprotect(PROTECT_USER);
db_multi_exec(
"UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid
);
zChngPw = mprintf(
"UPDATE user"
" SET pw=shared_secret(%Q,%Q,"
" (SELECT value FROM config WHERE name='project-code'))"
" WHERE login=%Q",
zNew1, g.zLogin, g.zLogin
);
fossil_free(zNewPw);
rc = login_group_sql(zChngPw, "<p>", "</p>\n", &zErr);
db_protect_pop();
if( rc ){
zErrMsg = mprintf("<span class=\"loginError\">%s</span>", zErr);
fossil_free(zErr);
}else{
redirect_to_g();
return;
}
| > > > > > > > > > > > | 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 |
;
}else{
char *zNewPw = sha1_shared_secret(zNew1, g.zLogin, 0);
char *zChngPw;
char *zErr;
int rc;
/* vvvvvvv--- tag-20230106-1 ----vvvvvv
**
** Replicate changes made below to tag-20230106-2
*/
admin_log("password change for user %s", g.zLogin);
db_unprotect(PROTECT_USER);
db_multi_exec(
"UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid
);
zChngPw = mprintf(
"UPDATE user"
" SET pw=shared_secret(%Q,%Q,"
" (SELECT value FROM config WHERE name='project-code'))"
" WHERE login=%Q",
zNew1, g.zLogin, g.zLogin
);
fossil_free(zNewPw);
rc = login_group_sql(zChngPw, "<p>", "</p>\n", &zErr);
db_protect_pop();
/*
** ^^^^^^^^--- tag-20230106-1 ----^^^^^^^^^
**
** Replicate changes above to tag-20230106-2
*/
if( rc ){
zErrMsg = mprintf("<span class=\"loginError\">%s</span>", zErr);
fossil_free(zErr);
}else{
redirect_to_g();
return;
}
|
| ︙ | ︙ | |||
768 769 770 771 772 773 774 775 776 777 778 779 780 781 |
@ <td><input type="submit" name="in" value="Login">
@ </tr>
if( !noAnon && login_self_register_available(0) ){
@ <tr>
@ <td></td>
@ <td><input type="submit" name="self" value="Create A New Account">
@ </tr>
}
@ </table>
if( zAnonPw && !noAnon ){
const char *zDecoded = captcha_decode(uSeed);
int bAutoCaptcha = db_get_boolean("auto-captcha", 0);
char *zCaptcha = captcha_render(zDecoded);
| > > > > > > | 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 |
@ <td><input type="submit" name="in" value="Login">
@ </tr>
if( !noAnon && login_self_register_available(0) ){
@ <tr>
@ <td></td>
@ <td><input type="submit" name="self" value="Create A New Account">
@ </tr>
}
if( login_self_password_reset_available() ){
@ <tr>
@ <td></td>
@ <td><input type="submit" name="pwreset" value="Reset My Password">
@ </tr>
}
@ </table>
if( zAnonPw && !noAnon ){
const char *zDecoded = captcha_decode(uSeed);
int bAutoCaptcha = db_get_boolean("auto-captcha", 0);
char *zCaptcha = captcha_render(zDecoded);
|
| ︙ | ︙ | |||
826 827 828 829 830 831 832 833 834 835 836 837 838 839 |
@ <td><input type="submit" value="Change Password" /></td></tr>
@ </table>
@ </form>
}
}
style_finish_page();
}
/*
** Attempt to find login credentials for user zLogin on a peer repository
** with project code zCode. Transfer those credentials to the local
** repository.
**
** Return true if a transfer was made and false if not.
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 |
@ <td><input type="submit" value="Change Password" /></td></tr>
@ </table>
@ </form>
}
}
style_finish_page();
}
/*
** Construct an appropriate URL suffix for the /resetpw page. The
** suffix will be of the form:
**
** UID-TIMESTAMP-HASH
**
** Where UID and TIMESTAMP are the parameters to this function, and HASH
** is constructed from information that is unique to the user in question
** and which is not publicly available. In particular, the HASH includes
** the existing user password. Thus, in order to construct a URL that can
** change a password, an attacker must know the current password, in which
** case the attacker does not need to construct the URL in order to take
** over the account.
**
** Return a pointer to the resulting string in memory obtained
** from fossil_malloc().
*/
char *login_resetpw_suffix(int uid, i64 timestamp){
char *zHash;
char *zInnerSql;
char *zResult;
extern int sqlite3_shathree_init(sqlite3*,char**,const sqlite3_api_routines*);
if( timestamp<=0 ){ timestamp = time(0); }
sqlite3_shathree_init(g.db, 0, 0);
if( db_table_exists("repository","subscriber") ){
zInnerSql = mprintf(
"SELECT %lld, login, pw, cookie, user.mtime, user.info, subscriberCode"
" FROM user LEFT JOIN subscriber ON suname=login"
" WHERE uid=%d", timestamp, uid);
}else{
zInnerSql = mprintf(
"SELECT %lld, login, pw, cookie, user.mtime, user.info"
" FROM user WHERE uid=%d", timestamp, uid);
}
zHash = db_text(0, "SELECT lower(hex(sha3_query(%Q)))", zInnerSql);
fossil_free(zInnerSql);
zResult = mprintf("%x-%llx-%s", uid, timestamp, zHash);
if( strlen(zHash)<64 || strlen(zResult)<70 ){
/* This should never happen, but if it does, we don't want it to lead
** to a security breach. */
fossil_panic("insecure password reset hash generated\n");
}
fossil_free(zHash);
return zResult;
}
/*
** Check to see if the "name" query parameter is a valid resetpw suffix
** for a user whose password we are allowed to reset. If it is, then return
** the positive integer UID for that user. If the query parameter is not
** valid, return 0.
*/
static int login_resetpw_suffix_is_valid(const char *zName){
int i, j;
int uid;
i64 timestamp;
i64 now;
char *zHash;
if( zName==0 || strlen(zName)<70 ) goto not_valid_suffix;
for(i=0; fossil_isxdigit(zName[i]); i++){}
if( i<1 || zName[i]!='-' ) goto not_valid_suffix;
for(j=i+1; fossil_isxdigit(zName[j]); j++){}
if( j<=i+1 || zName[j]!='-' ) goto not_valid_suffix;
uid = strtol(zName, 0, 16);
if( uid<=0 ) goto not_valid_suffix;
if( !db_exists("SELECT 1 FROM user WHERE uid=%d", uid) ){
goto not_valid_suffix;
}
timestamp = strtoll(&zName[i+1], 0, 16);
now = time(0);
if( timestamp+3600 <= now ) goto not_valid_suffix;
zHash = login_resetpw_suffix(uid,timestamp);
if( fossil_strcmp(zHash, zName)!=0 ){
fossil_free(zHash);
goto not_valid_suffix;
}
fossil_free(zHash);
return uid;
not_valid_suffix:
return 0;
}
/*
** COMMAND: test-resetpw-url
** Usage: fossil test-resetpw-url UID
**
** Generate and verify a /resetpw URL for user UID.
**
** This command is intended for unit testing the login_resetpw_suffix()
** and login_resetpw_suffix_is_valid() functions.
*/
void test_resetpw_url(void){
char *zSuffix;
int uid;
int xuid;
char *zLogin;
int i;
db_find_and_open_repository(0, 0);
verify_all_options();
if( g.argc<3 ){
usage("UID ...");
}
for(i=2; i<g.argc; i++){
uid = atoi(g.argv[i]);
zSuffix = login_resetpw_suffix(uid, 0);
xuid = login_resetpw_suffix_is_valid(zSuffix);
if( xuid>0 ){
zLogin = db_text(0, "SELECT login FROM user WHERE uid=%d", xuid);
}else{
zLogin = 0;
}
fossil_print("/resetpw/%s %d (%s)\n",
zSuffix, xuid, zLogin ? zLogin : "???");
fossil_free(zSuffix);
fossil_free(zLogin);
}
}
/*
** WEBPAGE: resetpw
**
** The URL format must be like this:
**
** /resetpw/UID-TIMESTAMP-HASH
**
** Where UID is the uid of the user whose password is to be reset,
** TIMESTAMP is the unix timestamp when the request was made, and
** HASH is a hash based on UID, TIMESTAMP, and other information that
** is unavailable to an attacher.
**
** With no other arguments, a form is present which allows the user to
** enter a new password. When the SUBMIT button is pressed, a POST request
** back to the same URL that will change the password.
*/
void login_resetpw(void){
const char *zName;
int uid;
char *zRPW;
const char *zNew1, *zNew2;
style_set_current_feature("resetpw");
style_header("Reset Password");
style_adunit_config(ADUNIT_OFF);
zName = PD("name","");
uid = login_resetpw_suffix_is_valid(zName);
if( uid==0 ){
@ <p><span class="loginError">
@ This password-reset URL is invalid, probably because it has expired.
@ Password-reset URLs have a short lifespan.
@ </span></p>
style_finish_page();
sleep(1); /* Introduce a small delay on an invalid suffix as an
** extra defense against search attacks */
return;
}
fossil_redirect_to_https_if_needed(1);
login_set_uid(uid, 0);
if( g.perm.Setup || g.perm.Admin || !g.perm.Password || g.zLogin==0 ){
@ <p><span class="loginError">
@ Cannot change the password for user <b>%h(g.zLogin)</b>.
@ </span></p>
style_finish_page();
return;
}
if( (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
if( fossil_strcmp(zNew1,zNew2)!=0 ){
@ <p><span class="loginError">
@ The two copies of your new passwords do not match.
@ Try again.
@ </span></p>
}else{
char *zNewPw = sha1_shared_secret(zNew1, g.zLogin, 0);
char *zChngPw;
char *zErr;
int rc;
/* vvvvvvv--- tag-20230106-2 ----vvvvvv
**
** Replicate changes made below to tag-20230106-1
*/
admin_log("password change for user %s", g.zLogin);
db_unprotect(PROTECT_USER);
db_multi_exec(
"UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid
);
zChngPw = mprintf(
"UPDATE user"
" SET pw=shared_secret(%Q,%Q,"
" (SELECT value FROM config WHERE name='project-code'))"
" WHERE login=%Q",
zNew1, g.zLogin, g.zLogin
);
fossil_free(zNewPw);
rc = login_group_sql(zChngPw, "<p>", "</p>\n", &zErr);
db_protect_pop();
/*
** ^^^^^^^^--- tag-20230106-2 ----^^^^^^^^^
**
** Replicate changes above to tag-20230106-1
*/
if( rc ){
@ <p><span class='loginError'>
@ %s(zErr);
@ </span></p>
fossil_free(zErr);
}else{
@ <p>Password changed successfully. Go to the
@ <a href="%R/login?u=%t(g.zLogin)">Login</a> page and log in
@ using the new password to continue.
@ </p>
style_finish_page();
return;
}
}
}
zRPW = fossil_random_password(12);
@ <p>Change Password for user <b>%h(g.zLogin)</b>:</p>
form_begin(0, "%R/resetpw");
@ <input type='hidden' name='name' value='%h(zName)'>
@ <table>
@ <tr><td class="form_label" id="newpw">New Password:</td>
@ <td><input aria-labelledby="newpw" type="password" name="n1" \
@ size="30" /> Suggestion: %z(zRPW)</td></tr>
@ <tr><td class="form_label" id="reppw">Repeat New Password:</td>
@ <td><input aria-labledby="reppw" type="password" name="n2" \
@ size="30" /></td></tr>
@ <tr><td></td>
@ <td><input type="submit" value="Change Password" /></td></tr>
@ </table>
@ </form>
style_finish_page();
}
/*
** Attempt to find login credentials for user zLogin on a peer repository
** with project code zCode. Transfer those credentials to the local
** repository.
**
** Return true if a transfer was made and false if not.
|
| ︙ | ︙ | |||
997 998 999 1000 1001 1002 1003 |
**
*/
void login_check_credentials(void){
int uid = 0; /* User id */
const char *zCookie; /* Text of the login cookie */
const char *zIpAddr; /* Raw IP address of the requestor */
const char *zCap = 0; /* Capability string */
| < | 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 |
**
*/
void login_check_credentials(void){
int uid = 0; /* User id */
const char *zCookie; /* Text of the login cookie */
const char *zIpAddr; /* Raw IP address of the requestor */
const char *zCap = 0; /* Capability string */
const char *zLogin = 0; /* Login user for credentials */
/* Only run this check once. */
if( g.userUid!=0 ) return;
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
constant_time_cmp_function, 0, 0);
|
| ︙ | ︙ | |||
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 |
/* If there is no user "nobody", then make one up - with no privileges */
uid = -1;
zCap = "";
}
sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "none");
}
/* At this point, we know that uid!=0. Find the privileges associated
** with user uid.
*/
assert( uid!=0 );
if( zCap==0 ){
Stmt s;
db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
| > > > > > > > > > > > | 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 |
/* If there is no user "nobody", then make one up - with no privileges */
uid = -1;
zCap = "";
}
sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "none");
}
login_set_uid(uid, zCap);
}
/*
** Set the current logged in user to be uid. zCap is precomputed
** (override) capabilities. If zCap==0, then look up the capabilities
** in the USER table.
*/
int login_set_uid(int uid, const char *zCap){
const char *zPublicPages = 0; /* GLOB patterns of public pages */
/* At this point, we know that uid!=0. Find the privileges associated
** with user uid.
*/
assert( uid!=0 );
if( zCap==0 ){
Stmt s;
db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
|
| ︙ | ︙ | |||
1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 |
const char *zUri = PD("REQUEST_URI","");
zUri += (int)strlen(g.zTop);
if( glob_match(pGlob, zUri) ){
login_set_capabilities(db_get("default-perms", "u"), 0);
}
glob_free(pGlob);
}
}
/*
** Memory of settings
*/
static int login_anon_once = 1;
| > | 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 |
const char *zUri = PD("REQUEST_URI","");
zUri += (int)strlen(g.zTop);
if( glob_match(pGlob, zUri) ){
login_set_capabilities(db_get("default-perms", "u"), 0);
}
glob_free(pGlob);
}
return g.zLogin!=0;
}
/*
** Memory of settings
*/
static int login_anon_once = 1;
|
| ︙ | ︙ | |||
1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 |
"UNION ALL "
"SELECT 1 FROM event WHERE user=%Q OR euser=%Q",
zUserID, zUserID, zUserID
);
return rc;
}
/*
** Check an email address and confirm that it is valid for self-registration.
** The email address is known already to be well-formed. Return true
** if the email address is on the allowed list.
**
** The default behavior is that any valid email address is accepted.
** But if the "auth-sub-email" setting exists and is not empty, then
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 |
"UNION ALL "
"SELECT 1 FROM event WHERE user=%Q OR euser=%Q",
zUserID, zUserID, zUserID
);
return rc;
}
/*
** zEMail is an email address. (Example: "xyz@gmail.com".) This routine
** searches for a user or subscriber that has that email address. If the
** email address is used no-where in the system, return 0. If the email
** address is assigned to a particular user return the UID for that user.
** If the email address is used, but not by a particular user, return -1.
*/
static int email_address_in_use(const char *zEMail){
int uid;
uid = db_int(0,
"SELECT uid FROM user"
" WHERE info LIKE '%%<%q>%%'", zEMail);
if( uid>0 ){
if( db_exists("SELECT 1 FROM user WHERE uid=%d AND ("
" cap GLOB '*[as]*' OR"
" find_emailaddr(info)<>%Q COLLATE nocase)",
uid, zEMail) ){
uid = -1;
}
}
if( uid==0 && alert_tables_exist() ){
uid = db_int(0,
"SELECT user.uid FROM subscriber JOIN user ON login=suname"
" WHERE semail=%Q AND sverified", zEMail);
if( uid ){
if( db_exists("SELECT 1 FROM user WHERE uid=%d AND "
" cap GLOB '*[as]*'",
uid) ){
uid = -1;
}
}
}
return uid;
}
/*
** COMMAND: test-email-used
** Usage: fossil test-email-used EMAIL ...
**
** Given a list of email addresses, show the UID and LOGIN associated
** with each one.
*/
void test_email_used(void){
int i;
db_find_and_open_repository(0, 0);
verify_all_options();
if( g.argc<3 ){
usage("EMAIL ...");
}
for(i=2; i<g.argc; i++){
const char *zEMail = g.argv[i];
int uid = email_address_in_use(zEMail);
if( uid==0 ){
fossil_print("%s: not used\n", zEMail);
}else if( uid<0 ){
fossil_print("%s: used but no password reset is available\n", zEMail);
}else{
char *zLogin = db_text(0, "SELECT login FROM user WHERE uid=%d", uid);
fossil_print("%s: UID %d (%s)\n", zEMail, uid, zLogin);
fossil_free(zLogin);
}
}
}
/*
** Check an email address and confirm that it is valid for self-registration.
** The email address is known already to be well-formed. Return true
** if the email address is on the allowed list.
**
** The default behavior is that any valid email address is accepted.
** But if the "auth-sub-email" setting exists and is not empty, then
|
| ︙ | ︙ | |||
1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 |
void register_page(void){
const char *zUserID, *zPasswd, *zConfirm, *zEAddr;
const char *zDName;
unsigned int uSeed;
const char *zDecoded;
int iErrLine = -1;
const char *zErr = 0;
int captchaIsCorrect = 0; /* True on a correct captcha */
char *zCaptcha = ""; /* Value of the captcha text */
char *zPerms; /* Permissions for the default user */
int canDoAlerts = 0; /* True if receiving email alerts is possible */
int doAlerts = 0; /* True if subscription is wanted too */
if( !db_get_boolean("self-register", 0) ){
style_header("Registration not possible");
@ <p>This project does not allow user self-registration. Please contact the
@ project administrator to obtain an account.</p>
style_finish_page();
return;
}
zPerms = db_get("default-perms", "u");
/* Prompt the user for email alerts if this repository is configured for
** email alerts and if the default permissions include "7" */
canDoAlerts = alert_tables_exist() && (db_int(0,
"SELECT fullcap(%Q) GLOB '*7*'", zPerms
| > > > > > > > > | 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 |
void register_page(void){
const char *zUserID, *zPasswd, *zConfirm, *zEAddr;
const char *zDName;
unsigned int uSeed;
const char *zDecoded;
int iErrLine = -1;
const char *zErr = 0;
int uid = 0; /* User id with the same email */
int captchaIsCorrect = 0; /* True on a correct captcha */
char *zCaptcha = ""; /* Value of the captcha text */
char *zPerms; /* Permissions for the default user */
int canDoAlerts = 0; /* True if receiving email alerts is possible */
int doAlerts = 0; /* True if subscription is wanted too */
if( !db_get_boolean("self-register", 0) ){
style_header("Registration not possible");
@ <p>This project does not allow user self-registration. Please contact the
@ project administrator to obtain an account.</p>
style_finish_page();
return;
}
if( P("pwreset")!=0 && login_self_password_reset_available() ){
/* The "Request Password Reset" button was pressed, so render the
** "Request Password Reset" page instead of this one. */
login_reqpwreset_page();
return;
}
zPerms = db_get("default-perms", "u");
/* Prompt the user for email alerts if this repository is configured for
** email alerts and if the default permissions include "7" */
canDoAlerts = alert_tables_exist() && (db_int(0,
"SELECT fullcap(%Q) GLOB '*7*'", zPerms
|
| ︙ | ︙ | |||
1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 |
zErr = "Not an authorized email address";
}else if( strlen(zPasswd)<6 ){
iErrLine = 4;
zErr = "Password must be at least 6 characters long";
}else if( fossil_strcmp(zPasswd,zConfirm)!=0 ){
iErrLine = 5;
zErr = "Passwords do not match";
}else if( login_self_choosen_userid_already_exists(zUserID) ){
iErrLine = 1;
zErr = "This User ID is already taken. Choose something different.";
| > > > < < < < < < < < < < < < < | 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 |
zErr = "Not an authorized email address";
}else if( strlen(zPasswd)<6 ){
iErrLine = 4;
zErr = "Password must be at least 6 characters long";
}else if( fossil_strcmp(zPasswd,zConfirm)!=0 ){
iErrLine = 5;
zErr = "Passwords do not match";
}else if( (uid = email_address_in_use(zEAddr))!=0 ){
iErrLine = 3;
zErr = "This email address is already associated with a user";
}else if( login_self_choosen_userid_already_exists(zUserID) ){
iErrLine = 1;
zErr = "This User ID is already taken. Choose something different.";
}else{
/* If all of the tests above have passed, that means that the submitted
** form contains valid data and we can proceed to create the new login */
Blob sql;
int uid;
char *zPass = sha1_shared_secret(zPasswd, zUserID, 0);
const char *zStartPerms = zPerms;
|
| ︙ | ︙ | |||
1807 1808 1809 1810 1811 1812 1813 |
@ </tr>
@ <tr>
@ <td class="form_label" align="right" id="emaddr">Email Address:</td>
@ <td><input aria-labelledby="emaddr" type="text" name="ea" \
@ value="%h(zEAddr)" size="30"></td>
@ </tr>
if( iErrLine==3 ){
| | > > > > > > | 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 |
@ </tr>
@ <tr>
@ <td class="form_label" align="right" id="emaddr">Email Address:</td>
@ <td><input aria-labelledby="emaddr" type="text" name="ea" \
@ value="%h(zEAddr)" size="30"></td>
@ </tr>
if( iErrLine==3 ){
@ <tr><td><td><span class='loginError'>↑ %h(zErr)</span>
if( uid>0 && login_self_password_reset_available() ){
@ <br />
@ <input type="submit" name="pwreset" \
@ value="Request Password Reset For %h(zEAddr)">
}
@ </td></tr>
}
if( canDoAlerts ){
int a = atoi(PD("alerts","1"));
@ <tr>
@ <td class="form_label" align="right" id="emalrt">Email Alerts?</td>
@ <td><select aria-labelledby="emalrt" size='1' name='alerts'>
@ <option value="1" %s(a?"selected":"")>Yes</option>
|
| ︙ | ︙ | |||
1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 | @ Enter this 8-letter code in the "Captcha" box above. @ </td></tr></table></div> @ </form> style_finish_page(); free(zCaptcha); } /* ** Run SQL on the repository database for every repository in our ** login group. The SQL is run in a separate database connection. ** ** Any members of the login group whose repository database file ** cannot be found is silently removed from the group. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 |
@ Enter this 8-letter code in the "Captcha" box above.
@ </td></tr></table></div>
@ </form>
style_finish_page();
free(zCaptcha);
}
/*
** WEBPAGE: reqpwreset
**
** A web page to request a password reset.
*/
void login_reqpwreset_page(void){
const char *zEAddr;
const char *zDecoded;
unsigned int uSeed;
int iErrLine = -1;
const char *zErr = 0;
int uid = 0; /* User id with the email zEAddr */
int captchaIsCorrect = 0; /* True on a correct captcha */
char *zCaptcha = ""; /* Value of the captcha text */
if( !login_self_password_reset_available() ){
style_header("Password reset not possible");
@ <p>This project does not allow users to reset their own passwords.
@ If you need a password reset, you will have to negotiate that directly
@ with the project administrator.
style_finish_page();
return;
}
zEAddr = PDT("ea","");
/* Verify user imputs */
if( !cgi_csrf_safe(1) || P("reqpwreset")==0 ){
/* This is the initial display of the form. No processing or error
** checking is to be done. Fall through into the form display
*/
}else if( (captchaIsCorrect = captcha_is_correct(1))==0 ){
iErrLine = 2;
zErr = "Incorrect CAPTCHA";
}else if( zEAddr[0]==0 ){
iErrLine = 1;
zErr = "Required";
}else if( email_address_is_valid(zEAddr,0)==0 ){
iErrLine = 1;
zErr = "Not a valid email address";
}else if( authorized_subscription_email(zEAddr)==0 ){
iErrLine = 1;
zErr = "Not an authorized email address";
}else if( (uid = email_address_in_use(zEAddr))<=0 ){
iErrLine = 1;
zErr = "This email address is not associated with a user who has "
"password reset privileges.";
}else if( login_set_uid(uid,0)==0 || g.perm.Admin || g.perm.Setup
|| !g.perm.Password ){
iErrLine = 1;
zErr = "This email address is not associated with a user who has "
"password reset privileges.";
}else{
/* If all of the tests above have passed, that means that the submitted
** form contains valid data and we can proceed to issue the password
** reset email. */
Blob hdr, body;
AlertSender *pSender;
char *zUrl = login_resetpw_suffix(uid, 0);
pSender = alert_sender_new(0,0);
blob_init(&hdr,0,0);
blob_init(&body,0,0);
blob_appendf(&hdr, "To: <%s>\n", zEAddr);
blob_appendf(&hdr, "Subject: Password reset for %s\n", g.zBaseURL);
blob_appendf(&body,
"Someone has requested to reset the password for user \"%s\"\n",
g.zLogin);
blob_appendf(&body, "at %s.\n\n", g.zBaseURL);
blob_appendf(&body,
"If you did not request this password reset, ignore\n"
"this email\n\n");
blob_appendf(&body,
"To reset the password, visit the following link:\n\n"
" %s/resetpw/%s\n\n", g.zBaseURL, zUrl);
fossil_free(zUrl);
alert_send(pSender, &hdr, &body, 0);
style_header("Email Verification");
if( pSender->zErr ){
@ <h1>Internal Error</h1>
@ <p>The following internal error was encountered while trying
@ to send the confirmation email:
@ <blockquote><pre>
@ %h(pSender->zErr)
@ </pre></blockquote>
}else{
@ <p>An email containing a hyperlink that can be used to reset
@ your password has been sent to "%h(zEAddr)".</p>
}
alert_sender_free(pSender);
style_finish_page();
return;
}
/* Prepare the captcha. */
if( captchaIsCorrect ){
uSeed = strtoul(P("captchaseed"),0,10);
}else{
uSeed = captcha_seed();
}
zDecoded = captcha_decode(uSeed);
zCaptcha = captcha_render(zDecoded);
style_header("Request Password Reset");
/* Print out the registration form. */
g.perm.Hyperlink = 1; /* Artificially enable hyperlinks */
form_begin(0, "%R/reqpwreset");
@ <p><input type="hidden" name="captchaseed" value="%u(uSeed)" />
@ <p><input type="hidden" name="reqpwreset" value="1" />
@ <table class="login_out">
@ <tr>
@ <td class="form_label" align="right" id="emaddr">Email Address:</td>
@ <td><input aria-labelledby="emaddr" type="text" name="ea" \
@ value="%h(zEAddr)" size="30"></td>
@ </tr>
if( iErrLine==1 ){
@ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr>
}
@ <tr>
@ <td class="form_label" align="right" id="cptcha">Captcha:</td>
@ <td><input type="text" name="captcha" aria-labelledby="cptcha" \
@ value="%h(captchaIsCorrect?zDecoded:"")" size="30">
captcha_speakit_button(uSeed, "Speak the captcha text");
@ </td>
@ </tr>
if( iErrLine==2 ){
@ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr>
}
@ <tr><td></td>
@ <td><input type="submit" name="new" value="Request Password Reset"/>\
@ </td></tr>
@ </table>
@ <div class="captcha"><table class="captcha"><tr><td><pre class="captcha">
@ %h(zCaptcha)
@ </pre>
@ Enter this 8-letter code in the "Captcha" box above.
@ </td></tr></table></div>
@ </form>
style_finish_page();
free(zCaptcha);
}
/*
** Run SQL on the repository database for every repository in our
** login group. The SQL is run in a separate database connection.
**
** Any members of the login group whose repository database file
** cannot be found is silently removed from the group.
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
2900 2901 2902 2903 2904 2905 2906 | ** option on interactive sessions to avoid that special processing when ** using this command interactively over SSH. A better solution would be ** to use a different command for "ssh" sync, but we cannot do that without ** breaking legacy. ** ** Options: ** --test Do not do special "sync" processing when operating | | | 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 |
** option on interactive sessions to avoid that special processing when
** using this command interactively over SSH. A better solution would be
** to use a different command for "ssh" sync, but we cannot do that without
** breaking legacy.
**
** Options:
** --test Do not do special "sync" processing when operating
** over an SSH link
** --th-trace Trace TH1 execution (for debugging purposes)
** --usercap CAP User capability string (Default: "sxy")
**
*/
void cmd_test_http(void){
const char *zIpAddr; /* IP address of remote client */
const char *zUserCap;
|
| ︙ | ︙ |
Changes to src/manifest.c.
| ︙ | ︙ | |||
1288 1289 1290 1291 1292 1293 1294 | ** ** Parse all entries in the BLOB table that are believed to be non-data ** artifacts and report any errors. Run this test command on historical ** repositories after making any changes to the manifest_parse() ** implementation to confirm that the changes did not break anything. ** ** Options: | < | 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 | ** ** Parse all entries in the BLOB table that are believed to be non-data ** artifacts and report any errors. Run this test command on historical ** repositories after making any changes to the manifest_parse() ** implementation to confirm that the changes did not break anything. ** ** Options: ** --limit N Parse no more than N artifacts before stopping ** --wellformed Use all BLOB table entries as input, not just ** those entries that are believed to be valid ** artifacts, and verify that the result the ** manifest_is_well_formed() agrees with the ** result of manifest_parse(). */ |
| ︙ | ︙ |
Changes to src/merge.c.
| ︙ | ︙ | |||
293 294 295 296 297 298 299 | ** a recent fork on the current branch to merge. ** ** Only file content is merged. The result continues to use the ** file and directory names from the current check-out even if those ** names might have been changed in the branch being merged in. ** ** Options: | < < < < < < < < < < | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
** a recent fork on the current branch to merge.
**
** Only file content is merged. The result continues to use the
** file and directory names from the current check-out even if those
** names might have been changed in the branch being merged in.
**
** Options:
** --backout Do a reverse cherrypick merge against VERSION.
** In other words, back out the changes that were
** added by VERSION.
** --baseline BASELINE Use BASELINE as the "pivot" of the merge instead
** of the nearest common ancestor. This allows
** a sequence of changes in a branch to be merged
** without having to merge the entire branch.
** --binary GLOBPATTERN Treat files that match GLOBPATTERN as binary
** and do not try to merge parallel changes. This
** option overrides the "binary-glob" setting.
** --cherrypick Do a cherrypick merge VERSION into the current
** check-out. A cherrypick merge pulls in the changes
** of the single check-in VERSION, rather than all
** changes back to the nearest common ancestor.
** -f|--force Force the merge even if it would be a no-op
** --force-missing Force the merge even if there is missing content
** --integrate Merged branch will be closed when committing
** -K|--keep-merge-files On merge conflict, retain the temporary files
** used for merging, named *-baseline, *-original,
** and *-merge.
** -n|--dry-run If given, display instead of run actions
** -v|--verbose Show additional details of the merge
*/
void merge_cmd(void){
int vid; /* Current version "V" */
int mid; /* Version we are merging from "M" */
int pid = 0; /* The pivot version - most recent common ancestor P */
int nid = 0; /* The name pivot version "N" */
|
| ︙ | ︙ |
Changes to src/name.c.
| ︙ | ︙ | |||
1061 1062 1063 1064 1065 1066 1067 | ** Usage: %fossil whatis NAME ** ** Resolve the symbol NAME into its canonical artifact hash ** artifact name and provide a description of what role that artifact ** plays. ** ** Options: | < | 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 |
** Usage: %fossil whatis NAME
**
** Resolve the symbol NAME into its canonical artifact hash
** artifact name and provide a description of what role that artifact
** plays.
**
** Options:
** -f|--file Find artifacts with the same hash as file NAME.
** If NAME is "-", read content from standard input.
** --type TYPE Only find artifacts of TYPE (one of: 'ci', 't',
** 'w', 'g', or 'e')
** -v|--verbose Provide extra information (such as the RID)
*/
void whatis_cmd(void){
|
| ︙ | ︙ |
Changes to src/patch.c.
| ︙ | ︙ | |||
843 844 845 846 847 848 849 850 851 852 853 854 | ** > fossil patch create [DIRECTORY] FILENAME ** ** Create a new binary patch in FILENAME that captures all uncommitted ** changes in the check-out at DIRECTORY, or the current directory if ** DIRECTORY is omitted. If FILENAME is "-" then the binary patch ** is written to standard output. ** ** -f|--force Overwrite an existing patch with the same name ** ** > fossil patch apply [DIRECTORY] FILENAME ** ** Apply the changes in FILENAME to the check-out at DIRECTORY, or | > | > | 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 | ** > fossil patch create [DIRECTORY] FILENAME ** ** Create a new binary patch in FILENAME that captures all uncommitted ** changes in the check-out at DIRECTORY, or the current directory if ** DIRECTORY is omitted. If FILENAME is "-" then the binary patch ** is written to standard output. ** ** Options: ** -f|--force Overwrite an existing patch with the same name ** ** > fossil patch apply [DIRECTORY] FILENAME ** ** Apply the changes in FILENAME to the check-out at DIRECTORY, or ** in the current directory if DIRECTORY is omitted. ** ** Options: ** -f|--force Apply the patch even though there are unsaved ** changes in the current check-out. Unsaved changes ** are reverted and permanently lost. ** -n|--dry-run Do nothing, but print what would have happened ** -v|--verbose Extra output explaining what happens ** ** > fossil patch diff [DIRECTORY] FILENAME |
| ︙ | ︙ |
Changes to src/pikchrshow.c.
| ︙ | ︙ | |||
523 524 525 526 527 528 529 | ** ** Accepts a pikchr script as input and outputs the rendered script as ** an SVG graphic. The INFILE and OUTFILE options default to stdin ** resp. stdout, and the names "-" can be used as aliases for those ** streams. ** ** Options: | < | 523 524 525 526 527 528 529 530 531 532 533 534 535 536 | ** ** Accepts a pikchr script as input and outputs the rendered script as ** an SVG graphic. The INFILE and OUTFILE options default to stdin ** resp. stdout, and the names "-" can be used as aliases for those ** streams. ** ** Options: ** -div On success, add a DIV wrapper around the ** resulting SVG output which limits its max-width to ** its computed maximum ideal size ** ** -div-indent Like -div but indent the div ** ** -div-center Like -div but center the div |
| ︙ | ︙ |
Changes to src/publish.c.
| ︙ | ︙ | |||
29 30 31 32 33 34 35 | ** ** Show a list of unpublished or "private" artifacts. Unpublished artifacts ** will never push and hence will not be shared with collaborators. ** ** By default, this command only shows unpublished check-ins. To show ** all unpublished artifacts, use the --all command-line option. ** | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
**
** Show a list of unpublished or "private" artifacts. Unpublished artifacts
** will never push and hence will not be shared with collaborators.
**
** By default, this command only shows unpublished check-ins. To show
** all unpublished artifacts, use the --all command-line option.
**
** Options:
** --all Show all artifacts, not just check-ins
*/
void unpublished_cmd(void){
int bAll = find_option("all",0,0)!=0;
db_find_and_open_repository(0,0);
verify_all_options();
|
| ︙ | ︙ |
Changes to src/regexp.c.
| ︙ | ︙ | |||
807 808 809 810 811 812 813 | ** ** Usage: %fossil test-grep REGEXP [FILE...] ** ** Run a regular expression match over the named disk files, or against ** standard input if no disk files are named on the command-line. ** ** Options: | < | 807 808 809 810 811 812 813 814 815 816 817 818 819 820 |
**
** Usage: %fossil test-grep REGEXP [FILE...]
**
** Run a regular expression match over the named disk files, or against
** standard input if no disk files are named on the command-line.
**
** Options:
** -i|--ignore-case Ignore case
*/
void re_test_grep(void){
ReCompiled *pRe;
const char *zErr;
int ignoreCase = find_option("ignore-case","i",0)!=0;
if( g.argc<3 ){
|
| ︙ | ︙ | |||
851 852 853 854 855 856 857 | ** be specified, in which case all named files are searched in reverse ** chronological order. ** ** For details of the supported regular expression dialect, see ** https://fossil-scm.org/fossil/doc/trunk/www/grep.md ** ** Options: | < | 850 851 852 853 854 855 856 857 858 859 860 861 862 863 | ** be specified, in which case all named files are searched in reverse ** chronological order. ** ** For details of the supported regular expression dialect, see ** https://fossil-scm.org/fossil/doc/trunk/www/grep.md ** ** Options: ** -c|--count Suppress normal output; instead print a count ** of the number of matching files ** -i|--ignore-case Ignore case ** -l|--files-with-matches List only hash for each match ** --once Stop searching after the first match ** -s|--no-messages Suppress error messages about nonexistent ** or unreadable files |
| ︙ | ︙ |
Changes to src/rss.c.
| ︙ | ︙ | |||
228 229 230 231 232 233 234 | /* ** COMMAND: rss* ** ** Usage: %fossil rss ?OPTIONS? ** ** The CLI variant of the /timeline.rss page, this produces an RSS | | > | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | /* ** COMMAND: rss* ** ** Usage: %fossil rss ?OPTIONS? ** ** The CLI variant of the /timeline.rss page, this produces an RSS ** feed of the timeline to stdout. ** ** Options: ** -type|y FLAG May be: all (default), ci (show check-ins only), ** t (show tickets only), w (show wiki only) ** ** -limit|n LIMIT The maximum number of items to show ** ** -tkt HASH Filter for only those events for the specified ticket ** |
| ︙ | ︙ |
Changes to src/search.c.
| ︙ | ︙ | |||
332 333 334 335 336 337 338 | ** ** Usage: %fossil test-match SEARCHSTRING FILE1 FILE2 ... ** ** Run the full-scan search algorithm using SEARCHSTRING against ** the text of the files listed. Output matches and snippets. ** ** Options: | < | 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
**
** Usage: %fossil test-match SEARCHSTRING FILE1 FILE2 ...
**
** Run the full-scan search algorithm using SEARCHSTRING against
** the text of the files listed. Output matches and snippets.
**
** Options:
** --begin TEXT Text to insert before each match
** --end TEXT Text to insert after each match
** --gap TEXT Text to indicate elided content
** --html Input is HTML
** --static Use the static Search object
*/
void test_match_cmd(void){
|
| ︙ | ︙ | |||
581 582 583 584 585 586 587 | ** Outputs, by default, some top-N fraction of the results. The -all ** option can be used to output all matches, regardless of their search ** score. The -limit option can be used to limit the number of entries ** returned. The -width option can be used to set the output width used ** when printing matches. ** ** Options: | < | 580 581 582 583 584 585 586 587 588 589 590 591 592 593 |
** Outputs, by default, some top-N fraction of the results. The -all
** option can be used to output all matches, regardless of their search
** score. The -limit option can be used to limit the number of entries
** returned. The -width option can be used to set the output width used
** when printing matches.
**
** Options:
** -a|--all Output all matches, not just best matches
** -n|--limit N Limit output to N matches
** -W|--width WIDTH Set display width to WIDTH columns, 0 for
** unlimited. Defaults the terminal's width.
*/
void search_cmd(void){
Blob pattern;
|
| ︙ | ︙ |
Changes to src/security_audit.c.
| ︙ | ︙ | |||
759 760 761 762 763 764 765 766 767 768 769 770 771 772 |
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_header("Server Error Log");
style_submenu_element("Test", "%R/test-warning");
style_submenu_element("Refresh", "%R/errorlog");
if( g.zErrlog==0 || fossil_strcmp(g.zErrlog,"-")==0 ){
@ <p>To create a server error log:
@ <ol>
@ <li><p>
@ If the server is running as CGI, then create a line in the CGI file
@ like this:
@ <blockquote><pre>
| > > > > | 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 |
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_header("Server Error Log");
style_submenu_element("Test", "%R/test-warning");
style_submenu_element("Refresh", "%R/errorlog");
style_submenu_element("Admin-Log", "admin_log");
style_submenu_element("User-Log", "access_log");
style_submenu_element("Artifact-Log", "rcvfromlist");
if( g.zErrlog==0 || fossil_strcmp(g.zErrlog,"-")==0 ){
@ <p>To create a server error log:
@ <ol>
@ <li><p>
@ If the server is running as CGI, then create a line in the CGI file
@ like this:
@ <blockquote><pre>
|
| ︙ | ︙ |
Changes to src/setup.c.
| ︙ | ︙ | |||
592 593 594 595 596 597 598 599 600 601 602 603 604 605 |
"self-register", "selfreg", 0, 0);
@ <p>Allow users to register themselves on the /register webpage.
@ A self-registration creates a new entry in the USER table and
@ perhaps also in the SUBSCRIBER table if email notification is
@ enabled.
@ (Property: "self-register")</p>
@ <hr />
onoff_attribute("Email verification required for self-registration",
"selfreg-verify", "sfverify", 0, 0);
@ <p>If enabled, self-registration creates a new entry in the USER table
@ with only capabilities "7". The default user capabilities are not
@ added until the email address associated with the self-registration
@ has been verified. This setting only makes sense if
| > > > > > > > > > | 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 |
"self-register", "selfreg", 0, 0);
@ <p>Allow users to register themselves on the /register webpage.
@ A self-registration creates a new entry in the USER table and
@ perhaps also in the SUBSCRIBER table if email notification is
@ enabled.
@ (Property: "self-register")</p>
@ <hr />
onoff_attribute("Allow users to reset their own passwords",
"self-pw-reset", "selfpw", 0, 0);
@ <p>Allow users to request that an email contains a hyperlink to a
@ password reset page be sent to their email address of record. This
@ enables forgetful users to recover their forgotten passwords without
@ administrator intervention.
@ (Property: "self-pw-reset")</p>
@ <hr />
onoff_attribute("Email verification required for self-registration",
"selfreg-verify", "sfverify", 0, 0);
@ <p>If enabled, self-registration creates a new entry in the USER table
@ with only capabilities "7". The default user capabilities are not
@ added until the email address associated with the self-registration
@ has been verified. This setting only makes sense if
|
| ︙ | ︙ | |||
1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 |
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_set_current_feature("setup");
style_header("Admin Log");
create_admin_log_table();
limit = atoi(PD("n","200"));
ofst = atoi(PD("x","0"));
fLogEnabled = db_get_boolean("admin-log", 0);
@ <div>Admin logging is %s(fLogEnabled?"on":"off").
@ (Change this on the <a href="setup_settings">settings</a> page.)</div>
| > > > | 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 |
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_set_current_feature("setup");
style_header("Admin Log");
style_submenu_element("User-Log", "access_log");
style_submenu_element("Artifact-Log", "rcvfromlist");
style_submenu_element("Error-Log", "errorlog");
create_admin_log_table();
limit = atoi(PD("n","200"));
ofst = atoi(PD("x","0"));
fLogEnabled = db_get_boolean("admin-log", 0);
@ <div>Admin logging is %s(fLogEnabled?"on":"off").
@ (Change this on the <a href="setup_settings">settings</a> page.)</div>
|
| ︙ | ︙ |
Changes to src/sha1.c.
| ︙ | ︙ | |||
499 500 501 502 503 504 505 | /* ** COMMAND: sha1sum* ** ** Usage: %fossil sha1sum FILE... ** ** Compute an SHA1 checksum of all files named on the command-line. ** If a file is named "-" then take its content from standard input. | < > | 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 | /* ** COMMAND: sha1sum* ** ** Usage: %fossil sha1sum FILE... ** ** Compute an SHA1 checksum of all files named on the command-line. ** If a file is named "-" then take its content from standard input. ** ** Options: ** -h|--dereference If FILE is a symbolic link, compute the hash ** on the object that the link points to. Normally, ** the hash is over the name of the object that ** the link points to. ** ** See also: [[md5sum]], [[sha3sum]] */ |
| ︙ | ︙ |
Changes to src/sha3.c.
| ︙ | ︙ | |||
626 627 628 629 630 631 632 | ** Compute an SHA3 checksum of all files named on the command-line. ** If a file is named "-" then take its content from standard input. ** ** To be clear: The official NIST FIPS-202 implementation of SHA3 ** with the added 01 padding is used, not the original Keccak submission. ** ** Options: | < | 626 627 628 629 630 631 632 633 634 635 636 637 638 639 | ** Compute an SHA3 checksum of all files named on the command-line. ** If a file is named "-" then take its content from standard input. ** ** To be clear: The official NIST FIPS-202 implementation of SHA3 ** with the added 01 padding is used, not the original Keccak submission. ** ** Options: ** --224 Compute a SHA3-224 hash ** --256 Compute a SHA3-256 hash (the default) ** --384 Compute a SHA3-384 hash ** --512 Compute a SHA3-512 hash ** --size N An N-bit hash. N must be a multiple of 32 between ** 128 and 512. ** -h|--dereference If FILE is a symbolic link, compute the hash on |
| ︙ | ︙ |
Changes to src/shun.c.
| ︙ | ︙ | |||
314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_header("Artifact Receipts");
if( showAll ){
ofst = 0;
}else{
style_submenu_element("All", "rcvfromlist?all=1");
}
if( ofst>0 ){
style_submenu_element("Newer", "rcvfromlist?ofst=%d",
| > > > | 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_header("Artifact Receipts");
style_submenu_element("Admin-Log", "admin_log");
style_submenu_element("User-Log", "access_log");
style_submenu_element("Error-Log", "errorlog");
if( showAll ){
ofst = 0;
}else{
style_submenu_element("All", "rcvfromlist?all=1");
}
if( ofst>0 ){
style_submenu_element("Newer", "rcvfromlist?ofst=%d",
|
| ︙ | ︙ |
Changes to src/smtp.c.
| ︙ | ︙ | |||
421 422 423 424 425 426 427 | ** Usage: %fossil test-smtp-probe DOMAIN [ME] ** ** Interact with the SMTP server for DOMAIN by setting up a connection ** and then immediately shutting it back down. Log all interaction ** on the console. Use ME as the domain name of the sender. ** ** Options: | < | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 |
** Usage: %fossil test-smtp-probe DOMAIN [ME]
**
** Interact with the SMTP server for DOMAIN by setting up a connection
** and then immediately shutting it back down. Log all interaction
** on the console. Use ME as the domain name of the sender.
**
** Options:
** --direct Use DOMAIN directly without going through MX
** --port N Talk on TCP port N
*/
void test_smtp_probe(void){
SmtpSession *p;
const char *zDomain;
const char *zSelf;
|
| ︙ | ︙ | |||
594 595 596 597 598 599 600 | ** ** Usage: %fossil test-smtp-send EMAIL FROM TO ... ** ** Use SMTP to send the email message contained in the file named EMAIL ** to the list of users TO. FROM is the sender of the email. ** ** Options: | < | 593 594 595 596 597 598 599 600 601 602 603 604 605 606 |
**
** Usage: %fossil test-smtp-send EMAIL FROM TO ...
**
** Use SMTP to send the email message contained in the file named EMAIL
** to the list of users TO. FROM is the sender of the email.
**
** Options:
** --direct Go directly to the TO domain. Bypass MX lookup
** --relayhost R Use R as relay host directly for delivery.
** --port N Use TCP port N instead of 25
** --trace Show the SMTP conversation on the console
*/
void test_smtp_send(void){
SmtpSession *p;
|
| ︙ | ︙ |
Changes to src/sqlcmd.c.
| ︙ | ︙ | |||
330 331 332 333 334 335 336 | ** ** WARNING: Careless use of this command can corrupt a Fossil repository ** in ways that are unrecoverable. Be sure you know what you are doing before ** running any SQL commands that modify the repository database. Use the ** --readonly option to prevent accidental damage to the repository. ** ** Options: | < < < < | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | ** ** WARNING: Careless use of this command can corrupt a Fossil repository ** in ways that are unrecoverable. Be sure you know what you are doing before ** running any SQL commands that modify the repository database. Use the ** --readonly option to prevent accidental damage to the repository. ** ** Options: ** --no-repository Skip opening the repository database ** --readonly Open the repository read-only. No changes ** are allowed. This is a recommended safety ** precaution to prevent repository damage. ** -R REPOSITORY Use REPOSITORY as the repository database ** --test Enable some testing and analysis features ** that are normally disabled. ** ** All of the standard sqlite3 command-line shell options should also ** work. ** ** The following SQL extensions are provided with this Fossil-enhanced |
| ︙ | ︙ |
Changes to src/stat.c.
| ︙ | ︙ | |||
331 332 333 334 335 336 337 | ** ** Usage: %fossil dbstat OPTIONS ** ** Shows statistics and global information about the repository and/or ** verify the integrity of a repository. ** ** Options: | < | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | ** ** Usage: %fossil dbstat OPTIONS ** ** Shows statistics and global information about the repository and/or ** verify the integrity of a repository. ** ** Options: ** -b|--brief Only show essential elements ** --db-check Run "PRAGMA quick_check" on the repository database ** --db-verify Run a full verification of the repository integrity. ** This involves decoding and reparsing all artifacts ** and can take significant time. ** --omit-version-info Omit the SQLite and Fossil version information */ |
| ︙ | ︙ |
Changes to src/sync.c.
| ︙ | ︙ | |||
317 318 319 320 321 322 323 | ** "configuration pull" command to pull website configuration details. ** ** If URL is not specified, then the URL from the most recent clone, push, ** pull, remote, or sync command is used. See "fossil help clone" for ** details on the URL formats. ** ** Options: | < | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | ** "configuration pull" command to pull website configuration details. ** ** If URL is not specified, then the URL from the most recent clone, push, ** pull, remote, or sync command is used. See "fossil help clone" for ** details on the URL formats. ** ** Options: ** --all Pull from all remotes, not just the default ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol, ** if required by the remote website ** --from-parent-project Pull content from the parent project ** --ipv4 Use only IPv4, not IPv6 ** --no-http-compression Do not compress HTTP traffic ** --once Do not remember URL for subsequent syncs |
| ︙ | ︙ | |||
372 373 374 375 376 377 378 | ** push" command to push website configuration details. ** ** If URL is not specified, then the URL from the most recent clone, push, ** pull, remote, or sync command is used. See "fossil help clone" for ** details on the URL formats. ** ** Options: | < | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | ** push" command to push website configuration details. ** ** If URL is not specified, then the URL from the most recent clone, push, ** pull, remote, or sync command is used. See "fossil help clone" for ** details on the URL formats. ** ** Options: ** --all Push to all remotes, not just the default ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol, ** if required by the remote website ** --ipv4 Use only IPv4, not IPv6 ** --no-http-compression Do not compress HTTP traffic ** --once Do not remember URL for subsequent syncs ** --proxy PROXY Use the specified HTTP proxy |
| ︙ | ︙ | |||
421 422 423 424 425 426 427 | ** edits to wiki pages, tickets, forum posts, and technical notes. ** ** If URL is not specified, then the URL from the most recent clone, push, ** pull, remote, or sync command is used. See "fossil help clone" for ** details on the URL formats. ** ** Options: | < | 419 420 421 422 423 424 425 426 427 428 429 430 431 432 | ** edits to wiki pages, tickets, forum posts, and technical notes. ** ** If URL is not specified, then the URL from the most recent clone, push, ** pull, remote, or sync command is used. See "fossil help clone" for ** details on the URL formats. ** ** Options: ** --all Sync with all remotes, not just the default ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol, ** if required by the remote website ** --ipv4 Use only IPv4, not IPv6 ** --no-http-compression Do not compress HTTP traffic ** --once Do not remember URL for subsequent syncs ** --proxy PROXY Use the specified HTTP proxy |
| ︙ | ︙ | |||
829 830 831 832 833 834 835 | ** is safe to run "fossil backup" on a repository that is in active use. ** ** Only the main repository database is backed up by this command. The ** open check-out file (if any) is not saved. Nor is the global configuration ** database. ** ** Options: | < | 826 827 828 829 830 831 832 833 834 835 836 837 838 839 |
** is safe to run "fossil backup" on a repository that is in active use.
**
** Only the main repository database is backed up by this command. The
** open check-out file (if any) is not saved. Nor is the global configuration
** database.
**
** Options:
** --overwrite OK to overwrite an existing file
** -R NAME Filename of the repository to backup
*/
void backup_cmd(void){
char *zDest;
int bOverwrite = 0;
db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
|
| ︙ | ︙ |
Changes to src/th_main.c.
| ︙ | ︙ | |||
2937 2938 2939 2940 2941 2942 2943 | ** Usage: %fossil test-th-render FILE ** ** Read the content of the file named "FILE" as if it were a header or ** footer or ticket rendering script, evaluate it, and show the results ** on standard output. ** ** Options: | < | 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 | ** Usage: %fossil test-th-render FILE ** ** Read the content of the file named "FILE" as if it were a header or ** footer or ticket rendering script, evaluate it, and show the results ** on standard output. ** ** Options: ** --cgi Include a CGI response header in the output ** --http Include an HTTP response header in the output ** --open-config Open the configuration database ** --set-anon-caps Set anonymous login capabilities ** --set-user-caps Set user login capabilities ** --th-trace Trace TH1 execution (for debugging purposes) */ |
| ︙ | ︙ | |||
2987 2988 2989 2990 2991 2992 2993 | ** Usage: %fossil test-th-eval SCRIPT ** ** Evaluate SCRIPT as if it were a header or footer or ticket rendering ** script and show the results on standard output. SCRIPT may be either ** a filename or a string of th1 script code. ** ** Options: | < | 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 | ** Usage: %fossil test-th-eval SCRIPT ** ** Evaluate SCRIPT as if it were a header or footer or ticket rendering ** script and show the results on standard output. SCRIPT may be either ** a filename or a string of th1 script code. ** ** Options: ** --cgi Include a CGI response header in the output ** --http Include an HTTP response header in the output ** --open-config Open the configuration database ** --set-anon-caps Set anonymous login capabilities ** --set-user-caps Set user login capabilities ** --th-trace Trace TH1 execution (for debugging purposes) */ |
| ︙ | ︙ | |||
3048 3049 3050 3051 3052 3053 3054 | ** Usage: %fossil test-th-source FILE ** ** Evaluate the contents of the file named "FILE" as if it were a header ** or footer or ticket rendering script and show the results on standard ** output. ** ** Options: | < | 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 | ** Usage: %fossil test-th-source FILE ** ** Evaluate the contents of the file named "FILE" as if it were a header ** or footer or ticket rendering script and show the results on standard ** output. ** ** Options: ** --cgi Include a CGI response header in the output ** --http Include an HTTP response header in the output ** --open-config Open the configuration database ** --set-anon-caps Set anonymous login capabilities ** --set-user-caps Set user login capabilities ** --th-trace Trace TH1 execution (for debugging purposes) ** --no-print-result Do not output the final result. Use if it |
| ︙ | ︙ | |||
3131 3132 3133 3134 3135 3136 3137 | ** and "web_flags" to appropriate values. ** ** webnotify Executes the TH1 procedure [webpage_notify], after ** setting the TH1 variables "web_name", "web_args", ** and "web_flags" to appropriate values. ** ** Options: | < | 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 |
** and "web_flags" to appropriate values.
**
** webnotify Executes the TH1 procedure [webpage_notify], after
** setting the TH1 variables "web_name", "web_args",
** and "web_flags" to appropriate values.
**
** Options:
** --cgi Include a CGI response header in the output
** --http Include an HTTP response header in the output
** --th-trace Trace TH1 execution (for debugging purposes)
*/
void test_th_hook(void){
int rc = TH_OK;
int nResult = 0;
|
| ︙ | ︙ |
Changes to src/unversioned.c.
| ︙ | ︙ | |||
248 249 250 251 252 253 254 | ** cat FILE ... Concatenate the content of FILEs to stdout. ** ** edit FILE Bring up FILE in a text editor for modification. ** ** export FILE OUTPUT Write the content of FILE into OUTPUT on disk ** ** list | ls Show all unversioned files held in the local | | > | > < | 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
** cat FILE ... Concatenate the content of FILEs to stdout.
**
** edit FILE Bring up FILE in a text editor for modification.
**
** export FILE OUTPUT Write the content of FILE into OUTPUT on disk
**
** list | ls Show all unversioned files held in the local
** repository.
**
** Options:
** --glob PATTERN Show only files that match
** --like PATTERN Show only files that match
** -l Show additional details for
** files that match. Implied
** when 'list' is used.
**
** revert ?URL? Restore the state of all unversioned files in the
** local repository to match the remote repository
** URL.
**
** Options:
** -v|--verbose Extra diagnostic output
** -n|--dry-run Show what would have happened
**
** remove|rm|delete FILE ...
** Remove unversioned files from the local repository.
** Changes are not pushed to other repositories until
** the next sync.
**
** Options:
** --glob PATTERN Remove files that match
** --like PATTERN Remove files that match
**
** sync ?URL? Synchronize the state of all unversioned files with
** the remote repository URL. The most recent version
** of each file is propagated to all repositories and
** all prior versions are permanently forgotten.
**
** Options:
** -v|--verbose Extra diagnostic output
** -n|--dry-run Show what would have happened
**
** touch FILE ... Update the TIMESTAMP on all of the listed files
**
** Options:
** --mtime TIMESTAMP Use TIMESTAMP instead of "now" for the "add",
** "edit", "remove", and "touch" subcommands.
** -R|--repository REPO Use FILE as the repository
*/
void unversioned_cmd(void){
const char *zCmd;
int nCmd;
|
| ︙ | ︙ |
Changes to src/url.c.
| ︙ | ︙ | |||
558 559 560 561 562 563 564 |
** If zMsg is not NULL and a proxy is used, then print zMsg followed
** by the canonical name of the proxy (with userid and password suppressed).
*/
void url_enable_proxy(const char *zMsg){
const char *zProxy;
zProxy = zProxyOpt;
if( zProxy==0 ){
| | | 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 |
** If zMsg is not NULL and a proxy is used, then print zMsg followed
** by the canonical name of the proxy (with userid and password suppressed).
*/
void url_enable_proxy(const char *zMsg){
const char *zProxy;
zProxy = zProxyOpt;
if( zProxy==0 ){
zProxy = db_get("proxy", "system");
if( fossil_strcmp(zProxy, "system")==0 ){
zProxy = fossil_getenv("http_proxy");
}
}
if( zProxy && zProxy[0] && !is_false(zProxy)
&& !g.url.isSsh && !g.url.isFile ){
char *zOriginalUrl = g.url.canonical;
|
| ︙ | ︙ |
Changes to src/user.c.
| ︙ | ︙ | |||
699 700 701 702 703 704 705 706 707 708 709 710 711 712 |
db_multi_exec("DELETE FROM accesslog WHERE rowid in"
"(SELECT rowid FROM accesslog ORDER BY rowid DESC"
" LIMIT -1 OFFSET 200)");
cgi_redirectf("%R/access_log?y=%d&n=%d", y, n);
return;
}
style_header("Access Log");
blob_zero(&sql);
blob_append_sql(&sql,
"SELECT uname, ipaddr, datetime(mtime,toLocal()), success"
" FROM accesslog"
);
if( zUser ){
blob_append_sql(&sql, " WHERE uname=%Q", zUser);
| > > > > | 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 |
db_multi_exec("DELETE FROM accesslog WHERE rowid in"
"(SELECT rowid FROM accesslog ORDER BY rowid DESC"
" LIMIT -1 OFFSET 200)");
cgi_redirectf("%R/access_log?y=%d&n=%d", y, n);
return;
}
style_header("Access Log");
style_submenu_element("Admin-Log", "admin_log");
style_submenu_element("Artifact-Log", "rcvfromlist");
style_submenu_element("Error-Log", "errorlog");
blob_zero(&sql);
blob_append_sql(&sql,
"SELECT uname, ipaddr, datetime(mtime,toLocal()), success"
" FROM accesslog"
);
if( zUser ){
blob_append_sql(&sql, " WHERE uname=%Q", zUser);
|
| ︙ | ︙ |
Changes to src/xfer.c.
| ︙ | ︙ | |||
1872 1873 1874 1875 1876 1877 1878 | ** The complete HTTP requests are stored in files named "http-request-N.txt". ** Find one of those requests, remove the HTTP header, and make other edits ** as necessary to generate an appropriate XFERFILE test case. Then run: ** ** fossil test-xfer xferfile.txt ** ** Options: | < | 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 |
** The complete HTTP requests are stored in files named "http-request-N.txt".
** Find one of those requests, remove the HTTP header, and make other edits
** as necessary to generate an appropriate XFERFILE test case. Then run:
**
** fossil test-xfer xferfile.txt
**
** Options:
** --host HOSTNAME Supply a server hostname used to populate
** g.zBaseURL and similar.
*/
void cmd_test_xfer(void){
const char *zHost;
db_find_and_open_repository(0,0);
zHost = find_option("host",0,1);
|
| ︙ | ︙ |
Changes to www/changes.wiki.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<title>Change Log</title>
<h2 id='v2_21'>Changes for version 2.21 (pending)</h2>
* Add the ability to put text descriptions on ticket report formats.
* Upgrade the test-find-pivot command to the [/help/merge-base|merge-base command].
* The [/help?cmd=/chat|/chat page] can now embed fossil-rendered
views of wiki/markdown/pikchr file attachments with the caveat that such
embedding happens in an iframe and thus does not inherit styles and such
from the containing browser window.
<h2 id='v2_20'>Changes for version 2.20 (2022-11-16)</h2>
* Added the [/help?cmd=chat-timeline-user|chat-timeline-user setting]. If
it is not an empty string, then any changes that would appear on the timeline
are announced in [./chat.md|the chat room].
* The /unsubscribe page now requests confirmation. [./alerts.md|Email notifications]
now contain only an "Unsubscribe" link, and not a link to subscription management.
| > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<title>Change Log</title>
<h2 id='v2_21'>Changes for version 2.21 (pending)</h2>
* Add the [/help?cmd=self-pw-reset|self-pw-reset property] and the
[/help?cmd=/resetpw|/resetpw page] and the [/help?cmd=/reqpwreset|/reqpwreset page]
while all work together to give users the ability to request a password
reset without administrator involvement.
* Add the ability to put text descriptions on ticket report formats.
* Upgrade the test-find-pivot command to the [/help/merge-base|merge-base command].
* The [/help?cmd=/chat|/chat page] can now embed fossil-rendered
views of wiki/markdown/pikchr file attachments with the caveat that such
embedding happens in an iframe and thus does not inherit styles and such
from the containing browser window.
* Passwords for remembered remote repositories are now stored as irreversible
hashes rather than obscured clear-text, for improved security.
* As additional defense-in-depth against attack, writes to the database
are disabled by default if the HTTP request does not come from the same origin.
<h2 id='v2_20'>Changes for version 2.20 (2022-11-16)</h2>
* Added the [/help?cmd=chat-timeline-user|chat-timeline-user setting]. If
it is not an empty string, then any changes that would appear on the timeline
are announced in [./chat.md|the chat room].
* The /unsubscribe page now requests confirmation. [./alerts.md|Email notifications]
now contain only an "Unsubscribe" link, and not a link to subscription management.
|
| ︙ | ︙ |
Changes to www/relatedwork.md.
1 2 3 4 | # Related Work ## Support Projects | | | | | | | | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # Related Work ## Support Projects * [SQLite]: C-language library that implements a small, fast, self-contained, high-reliability, full-featured, SQL database engine * [pikchr]: PIC-like markup language for diagrams in technical documentation * [althttpd]: simple, secure, and low resource usage webserver that has run the https://sqlite.org/ website since 2004 * [Lemon Parser Generator][lemon]: re-entrant and thread-safe LALR(1) parser with a less error-prone grammar syntax than YACC or BISON * [Makeheaders]: automatically generate header files for C/C++ projects ## Fossil Inspired Projects * [libfossil]: 3rd party Fossil SCM Library API * [fnc]: interactive text-based user interface for Fossil * [ChiselApp]: Free Fossil SCM hosting! * [Inskinerator]: The Fossil Skin Generator * [Fuel]: cross-platform GUI front-end for the excellent Fossil SCM * [fsl]: Tcl/Expect wrapper script extending Fossil functionality ## Editor Plugins * [Emacs-Fossil][emacsfsl]: GNU Emacs VC backend for the Fossil version control system * [VS Code][vscode]: Integrated Fossil source control in Visual Studio Code * [Qt Creator Plugin][qtfsl]: Fossil SCM plugin for the Qt Creator IDE |
| ︙ | ︙ | |||
55 56 57 58 59 60 61 | * [Tcl]: a simple-to-learn yet very powerful programming language [althttpd]: https://sqlite.org/althttpd/doc/trunk/althttpd.md [bsdtalk]: https://bsdtalk.blogspot.com/2010/07/bsdtalk194-fossil-scm-with-d-richard.html [changelog201]: https://changelog.com/podcast/201 [changelog454]: https://changelog.com/podcast/454 | | > | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | * [Tcl]: a simple-to-learn yet very powerful programming language [althttpd]: https://sqlite.org/althttpd/doc/trunk/althttpd.md [bsdtalk]: https://bsdtalk.blogspot.com/2010/07/bsdtalk194-fossil-scm-with-d-richard.html [changelog201]: https://changelog.com/podcast/201 [changelog454]: https://changelog.com/podcast/454 [ChiselApp]: https://chiselapp.com/ [CLion]: https://www.jetbrains.com/clion/ [corec66]: https://corecursive.com/066-sqlite-with-richard-hipp/ [Darcs]: http://darcs.net/ [db2w]: https://youtu.be/2eaQzahCeh4 [emacsfsl]: https://chiselapp.com/user/venks/repository/emacs-fossil/doc/tip/README.md [floss26]: https://twit.tv/shows/floss-weekly/episodes/26 [fnc]: https://fnc.bsdbox.org [fsl]: http://fossil.0branch.com/fsl [Fuel]: https://fuel-scm.org/fossil/index [Git]: https://git-scm.com [GoLand]: https://www.jetbrains.com/go/ [got]: https://gameoftrees.org [Inskinerator]: https://tangentsoft.com/inskinerator [IntelliJ]: https://www.jetbrains.com/idea/ [jetbrains]: https://plugins.jetbrains.com/plugin/7479-fossil-integration |
| ︙ | ︙ |