1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
-
+
|
#!/bin/sh
# Copyright (c) 2006-2011 WorkWare Systems http://www.workware.net.au/
# All rights reserved
# vim:se syntax=tcl:
# \
dir=`dirname "$0"`; exec "`$dir/autosetup-find-tclsh`" "$0" "$@"
# Note that the version has a trailing + on unreleased versions
set autosetup(version) 0.7.0+
set autosetup(version) 0.6.9
# Can be set to 1 to debug early-init problems
set autosetup(debug) [expr {"--debug" in $argv}]
##################################################################
#
# Main flow of control, option handling
|
︙ | | |
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
-
+
-
+
-
-
+
+
|
# At the is point we don't know what is a valid option
# We simply parse anything that looks like an option
set autosetup(getopt) [getopt argv]
#"=Core Options:"
options-add {
help:=all => "display help and options. Optional: module name, such as --help=system"
help:=local => "display help and options. Optionally specify a module name, such as --help=system"
licence license => "display the autosetup license"
version => "display the version of autosetup"
version => "display the version of autosetup"
ref:=text manual:=text
reference:=text => "display the autosetup command reference. 'text', 'wiki', 'asciidoc' or 'markdown'"
debug => "display debugging output as autosetup runs"
install:=. => "install autosetup to the current or given directory"
debug => "display debugging output as autosetup runs"
install:=. => "install autosetup to the current or given directory"
}
if {$autosetup(installed)} {
# hidden options so we can produce a nice error
options-add {
sysinstall:path
}
} else {
|
︙ | | |
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
|
-
+
-
-
+
-
-
-
-
+
-
-
-
-
+
+
|
} else {
user-error "Unexpected parameter: $arg"
}
}
autosetup_add_dep $autosetup(autodef)
# Add $argv to CONFIGURE_OPTS, but ignore duplicates and quote if needed
define CONFIGURE_OPTS ""
set configure_opts {}
foreach arg $autosetup(argv) {
set quoted [quote-if-needed $arg]
define-append CONFIGURE_OPTS [quote-if-needed $arg]
# O(n^2), but n will be small
if {$quoted ni $configure_opts} {
lappend configure_opts $quoted
}
}
}
define CONFIGURE_OPTS [join $configure_opts]
define AUTOREMAKE [file-normalize $autosetup(exe)]
define-append AUTOREMAKE [get-define CONFIGURE_OPTS]
# Log how we were invoked
configlog "Invoked as: [getenv WRAPPER $::argv0] [quote-argv $autosetup(argv)]"
configlog "Tclsh: [info nameofexecutable]"
# Load auto.def as module "auto.def"
autosetup_load_module auto.def source $autosetup(autodef)
# Note that auto.def is *not* loaded in the global scope
source $autosetup(autodef)
# Could warn here if options {} was not specified
show-notices
if {$autosetup(debug)} {
msg-result "Writing all defines to config.log"
|
︙ | | |
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
|
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
|
-
-
+
+
|
set result [lindex [dict get $::autosetup(optset) $opt] end]
}
}
if {![info exists result]} {
# No user-specified value. Has options-defaults been set?
foreach opt $names {
if {[dict exists $::autosetup(optdefault) $opt]} {
set result [dict get $autosetup(optdefault) $opt]
if {[dict exists $::autosetup(options-defaults) $opt]} {
set result [dict get $autosetup(options-defaults) $opt]
}
}
}
if {[info exists result]} {
set value $result
if {$retopt} {
|
︙ | | |
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
|
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
|
-
+
-
+
+
|
}
}
}
# Parse the option definition in $opts and update
# ::autosetup(setoptions) and ::autosetup(optionhelp) appropriately
#
proc options-add {opts} {
proc options-add {opts {header ""}} {
global autosetup
# First weed out comment lines
set realopts {}
foreach line [split $opts \n] {
if {![string match "#*" [string trimleft $line]]} {
append realopts $line \n
}
}
set opts $realopts
for {set i 0} {$i < [llength $opts]} {incr i} {
set opt [lindex $opts $i]
if {[string match =* $opt]} {
# This is a special heading
lappend autosetup(optionhelp) [list $opt $autosetup(module)]
lappend autosetup(optionhelp) $opt ""
set header {}
continue
}
unset -nocomplain defaultvalue equal value
#puts "i=$i, opt=$opt"
regexp {^([^:=]*)(:)?(=)?(.*)$} $opt -> name colon equal value
if {$name in $autosetup(options)} {
|
︙ | | |
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
|
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
|
-
-
+
+
+
-
-
+
+
-
|
dict set autosetup(optset) $name $setvalue
#puts "Found boolean option --$name=$setvalue"
}
} else {
# String option.
lappend autosetup(options) $name
if {$equal ne "="} {
# Was the option given as "name:value=default"?
if {$colon eq ":"} {
# Was ":name=default" given?
# If so, set $value to the display name and $defaultvalue to the default
# (This is the preferred way to set a default value for a string option)
if {[regexp {^([^=]+)=(.*)$} $value -> value defaultvalue]} {
dict set autosetup(optdefault) $name $defaultvalue
}
}
# Maybe override the default value
if {[dict exists $autosetup(options-defaults) $name]} {
# A default was specified with options-defaults, so use it
set defaultvalue [dict get $autosetup(options-defaults) $name]
dict set autosetup(optdefault) $name $defaultvalue
} elseif {![info exists defaultvalue]} {
# For backward compatibility, if ":name" was given, use name as both
# No default value was given by value=default or options-defaults
# so use the value as the default when the plain option with no
# the display text and the default value, but only if the user
# specified the option without the value
# value is given (.e.g. just --opt instead of --opt=value)
set defaultvalue $value
}
if {$equal eq "="} {
# String option with optional value
set opthelp "--$name?=$value?"
} else {
|
︙ | | |
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
|
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
|
+
+
+
+
+
-
+
-
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
|
}
# Now create the help for this option if appropriate
if {[lindex $opts $i+1] eq "=>"} {
set desc [lindex $opts $i+2]
if {[info exists defaultvalue]} {
set desc [string map [list @default@ $defaultvalue] $desc]
}
#string match \n* $desc
if {$header ne ""} {
lappend autosetup(optionhelp) $header ""
set header ""
}
# A multi-line description
lappend autosetup(optionhelp) [list $opthelp $autosetup(module) $desc]
lappend autosetup(optionhelp) $opthelp $desc
incr i 2
}
}
}
# @module-options optionlist
#
# Deprecated. Simply use 'options' from within a module.
# Like 'options', but used within a module.
proc module-options {opts} {
set header ""
if {$::autosetup(showhelp) > 1 && [llength $opts]} {
set header "Module Options:"
}
options $opts
options-add $opts $header
if {$::autosetup(showhelp)} {
# Ensure that the module isn't executed on --help
# We are running under eval or source, so use break
# to prevent further execution
#return -code break -level 2
return -code break
}
}
proc max {a b} {
expr {$a > $b ? $a : $b}
}
proc options-wrap-desc {text length firstprefix nextprefix initial} {
|
︙ | | |
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
|
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
|
-
-
-
+
-
-
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
|
set space " "
}
if {$len} {
puts ""
}
}
# Display options (from $autosetup(optionhelp)) for modules that match
# glob pattern $what
proc options-show {what} {
proc options-show {} {
set local 0
# Determine the max option width
set max 0
foreach help $::autosetup(optionhelp) {
foreach {opt desc} $::autosetup(optionhelp) {
lassign $help opt module desc
if {![string match $what $module]} {
continue
}
if {[string match =* $opt] || [string match \n* $desc]} {
continue
}
set max [max $max [string length $opt]]
}
set indent [string repeat " " [expr $max+4]]
set cols [getenv COLUMNS 80]
catch {
lassign [exec stty size] rows cols
}
incr cols -1
# Now output
foreach help $::autosetup(optionhelp) {
foreach {opt desc} $::autosetup(optionhelp) {
lassign $help opt module desc
if {![string match $what $module]} {
continue
}
if {$local == 0 && $module eq "auto.def"} {
puts "Local Options:"
incr local
}
if {[string match =* $opt]} {
# Output a special heading line"
puts [string range $opt 1 end]
continue
}
puts -nonewline " [format %-${max}s $opt]"
if {[string match \n* $desc]} {
# Output a pre-formatted help description as-is
puts $desc
} else {
options-wrap-desc [string trim $desc] $cols " " $indent [expr $max + 2]
}
}
}
|
︙ | | |
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
|
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
|
-
+
-
+
-
-
-
-
-
+
-
-
-
+
+
-
-
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
-
|
#
## name[=0|1] => "Description of this boolean option"
#
# The default is 'name=0', meaning that the option is disabled by default.
# If 'name=1' is used to make the option enabled by default, the description should reflect
# that with text like "Disable support for ...".
#
# An argument option (one which takes a parameter) is of one of the following forms:
# An argument option (one which takes a parameter) is of the form:
#
## name:value => "Description of this option"
## name:[=]value => "Description of this option"
## name:value=default => "Description of this option with a default value"
## name:=value => "Description of this option with an optional value"
#
# If the 'name:value' form is used, the value must be provided with the option (as '--name=myvalue').
# If the 'name:value=default' form is used, the option has the given default value even if not
# specified by the user.
# If the 'name:=value' form is used, the value is optional and the given value is used
# If the 'name:=value' form is used, the value is optional and the given value is used as the default
# if it is not provided.
#
# The description may contain '@default@', in which case it will be replaced with the default
# value for the option (taking into account defaults specified with 'options-defaults'.
#
# Undocumented options are also supported by omitting the '=> description'.
# These options are not displayed with '--help' and can be useful for internal options or as aliases.
#
# For example, '--disable-lfs' is an alias for '--disable=largefile':
#
## lfs=1 largefile=1 => "Disable large file support"
#
proc options {optlist} {
global autosetup
options-add $optlist
# Allow options as a list or args
options-add $optlist "Local Options:"
if {$autosetup(showhelp)} {
# If --help, stop now to show help
if {$::autosetup(showhelp)} {
options-show
exit 0
return -code break
}
if {$autosetup(module) eq "auto.def"} {
# Check for invalid options
if {[opt-bool option-checking]} {
foreach o [dict keys $::autosetup(getopt)] {
if {$o ni $::autosetup(options)} {
user-error "Unknown option --$o"
# Check for invalid options
if {[opt-bool option-checking]} {
foreach o [dict keys $::autosetup(getopt)] {
if {$o ni $::autosetup(options)} {
user-error "Unknown option --$o"
}
}
}
}
}
# @options-defaults dictionary
#
|
︙ | | |
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
|
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
|
-
-
+
-
+
-
+
-
+
-
-
-
-
-
+
-
-
|
lappend dirs $autosetup(srcdir)/autosetup
}
foreach m $args {
if {[info exists libmodule($m)]} {
continue
}
set libmodule($m) 1
if {[info exists modsource(${m}.tcl)]} {
autosetup_load_module $m eval $modsource(${m}.tcl)
automf_load eval $modsource(${m}.tcl)
} else {
set locs [list ${m}.tcl ${m}/init.tcl]
set found 0
foreach dir $dirs {
foreach loc $locs {
set source $dir/$loc
if {[file exists $source]} {
incr found
break
}
}
if {$found} {
break
}
}
if {$found} {
# For the convenience of the "use" source, point to the directory
# it is being loaded from
set ::usedir [file dirname $source]
autosetup_load_module $m source $source
automf_load source $source
autosetup_add_dep $source
} else {
autosetup-error "use: No such module: $m"
}
}
}
}
proc autosetup_load_auto_modules {} {
global autosetup modsource
# First load any embedded auto modules
foreach mod [array names modsource *.auto] {
autosetup_load_module $mod eval $modsource($mod)
automf_load eval $modsource($mod)
}
# Now any external auto modules
foreach file [glob -nocomplain $autosetup(libdir)/*.auto $autosetup(libdir)/*/*.auto] {
autosetup_load_module [file tail $file] source $file
automf_load source $file
}
}
# Load module source in the global scope by executing the given command
proc autosetup_load_module {module args} {
global autosetup
set prev $autosetup(module)
set autosetup(module) $module
proc automf_load {args} {
if {[catch [list uplevel #0 $args] msg opts] ni {0 2 3}} {
autosetup-full-error [error-dump $msg $opts $::autosetup(debug)]
}
set autosetup(module) $prev
}
# Initial settings
set autosetup(exe) $::argv0
set autosetup(istcl) 1
set autosetup(start) [clock millis]
set autosetup(installed) 0
set autosetup(sysinstall) 0
set autosetup(msg-checking) 0
set autosetup(msg-quiet) 0
set autosetup(inittypes) {}
set autosetup(module) autosetup
# Embedded modules are inserted below here
set autosetup(installed) 1
set autosetup(sysinstall) 0
# ----- @module asciidoc-formatting.tcl -----
set modsource(asciidoc-formatting.tcl) {
|
︙ | | |
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
|
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
|
-
+
-
-
-
+
+
+
-
-
-
-
+
+
-
-
-
+
+
+
+
+
-
+
|
proc autosetup_help {what} {
use_pager
puts "Usage: [file tail $::autosetup(exe)] \[options\] \[settings\]\n"
puts "This is [autosetup_version], a build environment \"autoconfigurator\""
puts "See the documentation online at http://msteveb.github.com/autosetup/\n"
if {$what in {all local}} {
if {$what eq "local"} {
# Need to load auto.def now
if {[file exists $::autosetup(autodef)]} {
# Load auto.def as module "auto.def"
autosetup_load_module auto.def source $::autosetup(autodef)
# This relies on auto.def having a call to 'options'
# which will display options and quit
source $::autosetup(autodef)
}
if {$what eq "all"} {
set what *
} else {
set what auto.def
options-show
}
} else {
incr ::autosetup(showhelp)
use $what
puts "Options for module $what:"
}
if {[catch {use $what}]} {
user-error "Unknown module: $what"
} else {
options-show
}
options-show $what
}
exit 0
}
proc autosetup_show_license {} {
global modsource autosetup
use_pager
|
︙ | | |
︙ | | |
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
-
-
-
+
+
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
#endif
/**
Various set-in-stone constants used by the API.
*/
enum fsl_hash_constants {
/**
The length, in bytes, of fossil's hex-form UUID strings.
FIXME: SHA3
The length, in bytes, of fossil's hex-form SHA1 UUID strings.
*/
FSL_UUIDv1_STRLEN = 40,
/**
The length, in bytes, of fossil's hex-form SHA3-256 UUID strings.
*/
FSL_UUID_STRLEN = 40,
FSL_UUIDv2_STRLEN = 64,
/**
The length, in bytes, of a hex-form MD5 hash.
*/
FSL_MD5_STRLEN = 32
FSL_MD5_STRLEN = 32,
FSL_UUID_STRLEN_MIN = FSL_UUIDv1_STRLEN,
FSL_UUID_STRLEN_MAX = FSL_UUIDv2_STRLEN
};
/**
Internal IDs for artifact hash types the library works.
*/
enum fsl_hash_types_t {
/** Invalid hash type. */
FSL_HTYPE_ERROR = 0,
/** SHA1. */
FSL_HTYPE_SHA1 = 1,
/** SHA3-256. */
FSL_HTYPE_K256 = 2
};
typedef enum fsl_hash_types_t fsl_hash_types_t;
enum fsl_hash_policy_t {
/* Use SHA1 hashes */
FSL_HPOLICY_SHA1 = 0,
/* SHA1 but auto-promote to SHA3 */
FSL_HPOLICY_AUTO = 1,
/* Use SHA3 hashes */
FSL_HPOLICY_SHA3 = 2,
/* Use SHA3 hashes exclusively */
FSL_HPOLICY_SHA3_ONLY = 3,
/* Shun all SHA1 objects */
FSL_HPOLICY_SHUN_SHA1 = 4
};
typedef enum fsl_hash_policy_t fsl_hash_policy_t;
typedef struct fsl_md5_cx fsl_md5_cx;
typedef struct fsl_sha1_cx fsl_sha1_cx;
typedef struct fsl_sha3_cx fsl_sha3_cx;
/**
|
︙ | | |
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
-
+
|
#endif
/**
Holds state for SHA1 calculations. It is intended to be used
like this:
@code
unsigned char digest[20]
char hex[FSL_UUID_STRLEN+1];
char hex[FSL_UUIDv1_STRLEN+1];
fsl_sha1_cx cx = fsl_sha1_cx_empty;
// alternately: fsl_sha1_init(&cx)
...call fsl_sha1_update(&cx,...) any number of times to
...incrementally calculate the hash.
fsl_sha1_final(&cx, digest); // ends the calculation
fsl_sha1_digest_to_base16(digest, hex);
// digest now contains the raw 20-byte SHA1 digest.
|
︙ | | |
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
|
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
|
+
+
+
+
+
+
+
+
-
-
-
+
+
+
|
returns 0.
@see fsl_sha1_update()
@see fsl_sha1_digest_to_base16()
*/
FSL_EXPORT int fsl_sha1_final(fsl_sha1_cx *context, unsigned char * digest);
/**
A convenience form of fsl_sha1_final() which writes
FSL_UUIDv1_STRLEN+1 bytes (hash plus terminating NUL byte) to the
2nd argument and returns a (const char *)-type cast of the 2nd
argument.
*/
FSL_EXPORT const char * fsl_sha1_final_hex(fsl_sha1_cx *context, char * zHex);
/**
Convert a digest into base-16. digest must be at least 20 bytes
long and hold an SHA1 digest. zBuf must be at least (FSL_UUID_STRLEN
+ 1) bytes long, for FSL_UUID_STRLEN characters of
hexidecimal-form SHA1 hash and 1 NUL byte.
long and hold an SHA1 digest. zBuf must be at least (FSL_UUIDv1_STRLEN
+ 1) bytes long, to which FSL_UUIDv1_STRLEN characters of
hexidecimal-form SHA1 hash and 1 NUL byte will be written.
@see fsl_sha1_final()
*/
FSL_EXPORT void fsl_sha1_digest_to_base16(unsigned char *digest, char *zBuf);
/**
Computes the SHA1 checksum of pIn and stores the resulting
|
︙ | | |
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
|
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
|
-
+
+
+
-
+
|
enum fsl_sha3_hash_size {
/** Sentinel value. Must be 0. */
FSL_SHA3_INVALID = 0,
FSL_SHA3_128 = 128, FSL_SHA3_160 = 160, FSL_SHA3_192 = 192,
FSL_SHA3_224 = 224, FSL_SHA3_256 = 256, FSL_SHA3_288 = 288,
FSL_SHA3_320 = 320, FSL_SHA3_352 = 352, FSL_SHA3_384 = 384,
FSL_SHA3_416 = 416, FSL_SHA3_448 = 448, FSL_SHA3_480 = 480,
FSL_SHA3_512 = 512
FSL_SHA3_512 = 512,
/* Default SHA3 flavor */
FSL_SHA3_DEFAULT = 256
};
/**
Type for holding SHA3 processing state. Each instance must be
initialized with fsl_sha3_init(), populated with fsl_sha3_update(),
and "sealed" with fsl_sha3_end().
Sample usage:
@code
fsl_sha3_cx cx;
fsl_sha3_init(&cx, FSL_SHA3_256);
fsl_sha3_init(&cx, FSL_SHA3_DEFAULT);
fsl_sha3_update(&cx, memory, lengthOfMemory);
fsl_sha3_end(&cx);
printf("Hash = %s\n", (char const *)cx.hex);
@endcode
After fsl_sha3_end() is called cx.hex contains the hex-string forms
of the digest. Note that fsl_sha3_update() may be called an arbitrary
|
︙ | | |
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
|
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
|
-
-
+
+
+
+
+
+
+
+
-
+
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
entry is returned, else FSL_SHA3_INVALID is returned.
@see fsl_sha3_init()
*/
FSL_EXPORT enum fsl_sha3_hash_size fsl_sha3_hash_size_for_int(int);
/**
Initialize a new hash. The second argument specifies the size of the hash
in bits. Results are undefined if cx is NULL or sz is not a valid value.
Initialize a new hash. The second argument specifies the size of
the hash in bits. Results are undefined if cx is NULL or sz is not
a valid positive value.
After calling this, use fsl_sha3_update() to hash data and
fsl_sha3_end() to finalize the hashing process and generate a digest.
*/
FSL_EXPORT void fsl_sha3_init2(fsl_sha3_cx *cx, enum fsl_sha3_hash_size sz);
/**
Equivalent to fsl_sha3_init2(cx, FSL_SHA3_DEFAULT).
*/
FSL_EXPORT void fsl_sha3_init(fsl_sha3_cx *cx, enum fsl_sha3_hash_size sz);
FSL_EXPORT void fsl_sha3_init(fsl_sha3_cx *cx);
/**
Updates cx's state to include the first len bytes of data.
If cx is NULL results are undefined (segfault!). If mem is not
NULL then it must be at least n bytes long. If n is 0 then this
function has no side-effects.
@see fsl_sha3_init()
@see fsl_sha3_end()
*/
FSL_EXPORT void fsl_sha3_update( fsl_sha3_cx *cx, void const *data, unsigned int len);
/**
To be called when hashing is complete: finishes the hash
To be called when SHA3 hashing is complete: finishes the hash
calculation and populates cx->hex with the final hash code in
hexidecimal-string form. Returns the binary-form digest value,
which refers to cx->size/8 bytes of memory which lives in the cx
object. After this call cx->hex will be populated with cx->size/4
bytes of lower-case ASCII hex codes plus a terminating NUL byte.
Potential TODO: change fsl_sha1_final() and fsl_md5_final() to use
these same return semantics.
@see fsl_sha3_init()
@see fsl_sha3_update()
*/
FSL_EXPORT unsigned char const * fsl_sha3_end(fsl_sha3_cx *cx);
/* TODOs: port the sha1 counterparts of these to sha3: */
/* TODO */FSL_EXPORT void fsl_sha3_digest_to_base16(unsigned char *digest, char *zBuf);
/* TODO */FSL_EXPORT int fsl_sha3sum_buffer(fsl_buffer const *pIn, fsl_buffer *pCksum);
/* TODO */FSL_EXPORT char *fsl_sha3sum_cstr(const char *zIn, fsl_int_t len);
/* TODO */FSL_EXPORT int fsl_sha3sum_stream(fsl_input_f src, void * srcState, fsl_buffer *pCksum);
/* TODO */FSL_EXPORT int fsl_sha1sum_filename(const char *zFilename, fsl_buffer *pCksum);
/**
SHA3-256 counterpart of fsl_sha1_digest_to_base16(). digest must be at least
32 bytes long and hold an SHA3 digest. zBuf must be at least (FSL_UUIDv2_STRLEN+1)
bytes long, to which FSL_UUIDv2_STRLEN characters of
hexidecimal-form SHA3 hash and 1 NUL byte will be written
@see fsl_sha3_end().
*/
FSL_EXPORT void fsl_sha3_digest_to_base16(unsigned char *digest, char *zBuf);
/**
SHA3 counter part of fsl_sha1sum_buffer().
*/
FSL_EXPORT int fsl_sha3sum_buffer(fsl_buffer const *pIn, fsl_buffer *pCksum);
/**
SHA3 counter part of fsl_sha1sum_cstr().
*/
FSL_EXPORT char *fsl_sha3sum_cstr(const char *zIn, fsl_int_t len);
/**
SHA3 counterpart of fsl_sha1sum_stream().
*/
FSL_EXPORT int fsl_sha3sum_stream(fsl_input_f src, void * srcState, fsl_buffer *pCksum);
/**
SHA3 counterpart of fsl_sha1sum_filename().
*/
FSL_EXPORT int fsl_sha3sum_filename(const char *zFilename, fsl_buffer *pCksum);
/**
Expects zHash to be a full-length hash value of one of the
fsl_hash_types_t-specified types, and nHash to be the length, in
bytes, of zHash's contents (which must be the full hash length, not
a prefix). If zHash can be validated as a hash, its corresponding
hash type is returned, else FSL_HTYPE_ERROR is returned.
*/
FSL_EXPORT fsl_hash_types_t fsl_validate_hash(const char *zHash, int nHash);
/**
Expects (zHash, nHash) to refer to a full hash (of a supported
content hash type) of pIn's contents. This routine hashes pIn's
contents and, if it compares equivalent to zHash then the ID of the
hash type is returned. On a mismatch, FSL_HTYPE_ERROR is returned.
*/
FSL_EXPORT fsl_hash_types_t fsl_verify_blob_hash(fsl_buffer const * pIn,
const char *zHash, int nHash);
/**
Sets f's hash policy and returns the previous value.
*/
FSL_EXPORT fsl_hash_policy_t fsl_cx_hash_policy_set(fsl_cx *f, fsl_hash_policy_t p);
/**
Returns f's current hash policy.
*/
FSL_EXPORT fsl_hash_policy_t fsl_cx_hash_policy_get(fsl_cx const*f);
/**
Returns a human-friendly name for f's current hash policy.
*/
FSL_EXPORT char const * fsl_cx_hash_policy_name(fsl_cx const*f);
/**
Returns a human-readable name for the given hash type, or its
second argument h is not a supported hash type.
*/
FSL_EXPORT const char * fsl_hash_type_name(fsl_hash_types_t h, const char *zUnknown);
#if defined(__cplusplus)
} /*extern "C"*/
#endif
#endif
/* NET_FOSSIL_SCM_FSL_HASH_H_INCLUDED */
|
︙ | | |
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
-
-
-
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
+
+
+
+
+
+
|
arguments. That depends on the routine which uses the comparison
function.
*/
typedef int (*fsl_generic_cmp_f)( void const * lhs, void const * rhs );
/**
fsl_uuid_str and fsl_uuid_cstr are "for documentation and
readability purposes" typedefs used to denote strings which the
API requires to be in the form of Fossil UUID strings. Such
strings are exactly FSL_UUID_STRLEN bytes long plus a
readability purposes" typedefs used to denote strings which the API
requires to be in the form of Fossil UUID strings. Such strings are
exactly FSL_UUIDv1_STRLEN or FSL_UUIDv2_STRLEN bytes long plus a
terminating NUL byte and contain only lower-case hexadecimal
bytes. Where this typedef is used, the library requires,
enforces, and/or assumes (at different times) that fsl_is_uuid()
returns true for such strings (if they are not NULL, though not
all contexts allow a NULL UUID). These typedef are _not_ used to
denote arguments which may refer to partial UUIDs or symbolic
names, only 100% bonafide Fossil UUIDs (which are different from
RFC4122 UUIDs).
bytes. Where this typedef is used, the library requires, enforces,
and/or assumes (at different times) that fsl_is_uuid() returns true
for such strings (if they are not NULL, though not all contexts
allow a NULL UUID). These typedef are _not_ used to denote
arguments which may refer to partial UUIDs or symbolic names, only
100% bonafide Fossil UUIDs (which are different from RFC4122
UUIDs).
The API guarantees that this typedef will always be (char *) and
that fsl_uuid_cstr will always ben (char const *), and thus it
is safe/portable to use those type instead of thse. These
is safe/portable to use those type instead of these. These
typedefs serve only to improve the readability of certain APIs
by implying (through the use of this typedef) the preconditions
defined for UUID strings.
@see fsl_is_uuid()
*/
typedef char * fsl_uuid_str;
/**
The const counterpart of fsl_uuid_str.
@see fsl_is_uuid()
*/
typedef char const * fsl_uuid_cstr;
/**
Returns true (non-0) if str is not NULL, is exactly
FSL_UUID_STRLEN bytes long (meaning its final byte is a NUL),
and contains only lower-case hexadecimal characters, else
returns false (0).
If the NUL-terminated input str is exactly FSL_UUIDv1_STRLEN or
FSL_UUIDv2_STRLEN bytes long and contains only lower-case
hexadecimal characters, returns the length of the string, else
returns 0.
Note that Fossil UUIDs are not RFC4122 UUIDs, but are SHA1
hash strings. Don't let that disturb you. As Tim Berners-Lee
writes:
Note that Fossil UUIDs are not RFC4122 UUIDs, but are SHA1 or
SHA3-256 hash strings. Don't let that disturb you. As Tim
Berners-Lee writes:
'The assertion that the space of URIs is a universal space
sometimes encounters opposition from those who feel there should
not be one universal space. These people need not oppose the
concept because it is not of a single universal space: Indeed,
the fact that URIs form universal space does not prevent anyone
else from forming their own universal space, which of course by
definition would be able to envelop within it as a subset the
universal URI space. Therefore the web meets the "independent
design" test, that if a similar system had been concurrently and
independently invented elsewhere, in such a way that the
arbitrary design decisions were made differently, when they met
later, the two systems could be made to interoperate.'
Source: https://www.w3.org/DesignIssues/Axioms.html
(Just mentally translate URI as UUID.)
*/
FSL_EXPORT char fsl_is_uuid(char const * str);
FSL_EXPORT int fsl_is_uuid(char const * str);
/**
If x is a valid fossil UUID length, it is returned, else 0 is returned.
*/
FSL_EXPORT int fsl_is_uuid_len(int x);
/**
Expects str to be a string containing an unsigned decimal
value. Returns its decoded value, or -1 on error.
*/
FSL_EXPORT fsl_size_t fsl_str_to_size(char const * str);
|
︙ | | |
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
|
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
|
-
+
+
+
+
+
+
+
+
+
+
+
|
/**
fsl_strcmp() variant which compares at most nByte bytes of the
given strings, case-sensitively. Returns 0 if nByte is 0.
*/
FSL_EXPORT int fsl_strncmp(const char *zA, const char *zB, fsl_size_t nByte);
/**
Equivalent to fsl_strncmp(lhs, rhs, FSL_UUID_STRLEN).
Equivalent to fsl_strncmp(lhs, rhs, X), where X is either
FSL_UUIDv1_STRLEN or FSL_UUIDv2_STRLEN: if both lhs and rhs are
longer than FSL_UUIDv1_STRLEN then they are assumed to be
FSL_UUIDv2_STRLEN bytes long and are compared as such, else they
are assumed to be FSL_UUIDv1_STRLEN bytes long and compared as
such.
Potential FIXME/TODO: if their lengths differ, i.e. one is v1 and
one is v2, compare them up to their common length then, if they
still compare equivalent, treat the shorter one as less-than the
longer.
*/
FSL_EXPORT int fsl_uuidcmp( fsl_uuid_cstr lhs, fsl_uuid_cstr rhs );
/**
Returns false if s is NULL or starts with any of (0 (NUL), '0'
(ASCII character zero), 'f', 'n', "off"), case-insensitively,
else it returns true.
|
︙ | | |
︙ | | |
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
-
+
+
|
Author contact information:
drh@hwaci.com
https://www.hwaci.com/drh/
*****************************************************************************
This file houses the code for the fsl_content_xxx() APIS.
*/
#include <assert.h>
#include "fossil-scm/fossil-internal.h"
#include <assert.h>
#include <memory.h> /* memcmp() */
/* Only for debugging */
#include <stdio.h>
#define MARKER(pfexp) \
do{ printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); \
printf pfexp; \
} while(0)
|
︙ | | |
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
|
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
|
+
-
+
-
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
+
+
+
+
+
+
+
-
+
|
fsl_stmt * s1 = NULL;
fsl_buffer cmpr = fsl_buffer_empty;
fsl_buffer hash = fsl_buffer_empty;
char markAsUnclustered = 0;
char markAsUnsent = 1;
char isDephantomize = 0;
fsl_db * dbR = fsl_cx_db_repo(f);
int const zUuidLen = zUuid ? fsl_is_uuid(zUuid) : 0;
int rc;
int rc = 0;
char inTrans = 0;
assert(f);
assert(dbR);
assert(pBlob);
assert(srcId==0 || zUuid!=NULL);
assert(!zUuid || fsl_is_uuid(zUuid));
assert(!zUuid || zUuidLen);
if(!dbR) return FSL_RC_NOT_A_REPO;
if(!zUuid){
assert(0==uncompSize);
/* "auxiliary hash" bits from:
https://fossil-scm.org/fossil/file?ci=c965636958eb58aa&name=src%2Fcontent.c&ln=527-537
*/
/* First check the auxiliary hash to see if there is already an artifact
** that uses the auxiliary hash name */
rc = fsl_sha1sum_buffer(pBlob, &hash);
rc = fsl_cx_hash_buffer(f, 1, pBlob, &hash);
if(rc) goto end;
assert(hash.used>=FSL_UUIDv1_STRLEN);
rid = fsl_uuid_to_rid(f, fsl_buffer_cstr(&hash));
assert(rid>=0 && "Cannot have malformed/ambiguous UUID at this point.");
if(!rid){
/* No existing artifact with the auxiliary hash name. Therefore, use
** the primary hash name. */
hash.used = 0;
rc = fsl_cx_hash_buffer(f, 0, pBlob, &hash);
if(rc) goto end;
assert(hash.used>=FSL_UUIDv1_STRLEN);
}
}else{
rc = fsl_buffer_append(&hash, zUuid, FSL_UUID_STRLEN);
rc = fsl_buffer_append(&hash, zUuid, zUuidLen);
}
if(rc) goto end;
if(rc) goto end;
}
assert(!rc);
if(uncompSize){
/* pBlob is assumed to be compressed. */
assert(fsl_buffer_is_compressed(pBlob));
size = uncompSize;
}else{
size = pBlob->used;
if(srcId>0){
rc = fsl_delta_applied_size(pBlob->mem, pBlob->used, &size);
if(rc) goto end;
}
}
rc = fsl_db_transaction_begin(dbR);
if(rc) goto end;
inTrans = 1;
if( f->cache.hashPolicy==FSL_HPOLICY_AUTO && hash.used>FSL_UUIDv1_STRLEN ){
f->cache.hashPolicy = FSL_HPOLICY_SHA3;
rc = fsl_config_set_int32(f, FSL_CONFDB_REPO, "hash-policy", FSL_HPOLICY_SHA3);
if(rc) goto end;
}
/* Check to see if the entry already exists and if it does whether
or not the entry is a phantom.
*/
rc = fsl_db_prepare_cached(dbR, &s1,
"SELECT rid, size FROM blob WHERE uuid=?");
if(rc) goto end;
rc = fsl_stmt_bind_text( s1, 1, fsl_buffer_cstr(&hash),
|
︙ | | |
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
|
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
|
-
+
|
TODO: figure out what that is.
*/
rc = fsl_content_mark_available(f, rid);
if(rc) goto end;
}
if( isDephantomize ){
#if 0
/* MISSING */
/* FIXME?: MISSING */
after_dephantomize(rid, 0);
#else
assert(!"Missing code: after_dephantomize()");
#endif
}
/* Add the element to the unclustered table if has never been
|
︙ | | |
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
|
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
|
-
-
|
"VALUES(%"FSL_ID_T_PFMT")", (fsl_id_t)rid);
if(rc) goto end;
}
rc = fsl_repo_verify_before_commit(f, rid);
if(rc) goto end /* FSL_RC_OOM is basically the "only possible" failure
after this point. */;
/* Code after end: relies on the following 2 lines: */
rc = fsl_db_transaction_end(dbR, 0);
inTrans = 0;
if(!rc){
if(outRid) *outRid = rid;
}
end:
if(inTrans){
assert(0!=rc);
fsl_db_transaction_end(dbR,1);
}
fsl_buffer_clear(&hash);
if(!uncompSize){
fsl_buffer_clear(&cmpr);
}/* else cmpr.mem (if any) belongs to pBlob */
return rc;
}
char fsl_acache_expire_oldest(fsl_acache * c){
fsl_int_t i;
fsl_int_t mnAge = c->nextAge;
fsl_int_t mn = -1;
for(i=0; i<(fsl_int_t)c->used; i++){
if( c->list[i].age<mnAge ){
|
︙ | | |
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
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
751
752
753
754
755
|
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
751
752
753
|
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
+
+
-
+
-
+
|
}
assert(!"delta-loop in repository");
return fsl_cx_err_set(f, FSL_RC_CONSISTENCY,
"Serious problem: delta-loop in repository");
}
int fsl_content_put( fsl_cx * f, fsl_buffer const * pBlob, fsl_id_t * newRid){
#if 1
return fsl_content_put_ex(f, pBlob, NULL, 0, 0, 0, newRid);
#else
/*
EXPERIMENT: if pBlob appears to be compressed, pass the proper
uncompressed size value (and required UUID) to put_ex().
}
Aaarrggg - there's the catch. We cannot know the UUID without
decompressing the data.
*/
fsl_int_t const ucSize = fsl_buffer_is_compressed(pBlob)
? fsl_buffer_uncompressed_size(pBlob)
: 0;
if(ucSize < 0) return FSL_RC_RANGE;
else{
fsl_buffer uuid = fsl_buffer_empty;
int rc = fsl_sha1sum_buffer(pBlob, &uuid);
if(!rc){
rc = fsl_content_put_ex(f, pBlob, fsl_buffer_cstr(&uuid), 0,
(fsl_size_t)ucSize, 0, newRid);
}
fsl_buffer_clear(&uuid);
return rc;
}
#endif
}
char fsl_uuid_is_shunned(fsl_cx * f, fsl_uuid_cstr zUuid){
int fsl_uuid_is_shunned(fsl_cx * f, fsl_uuid_cstr zUuid){
fsl_int32_t i = 0;
fsl_db * db = fsl_cx_db_repo(f);
if( !db || zUuid==0 || zUuid[0]==0 ) return 0;
i = fsl_db_g_int32( db, 0,
"SELECT 1 FROM shun WHERE uuid=%Q",
zUuid);
return 1==i;
}
int fsl_content_new( fsl_cx * f, fsl_uuid_cstr uuid, char isPrivate,
fsl_id_t * newId ){
fsl_id_t rid = 0;
int rc;
fsl_db * db = fsl_cx_db_repo(f);
fsl_stmt * s1 = NULL, * s2 = NULL;
int const uuidLen = uuid ? fsl_is_uuid(uuid) : 0;
if(!f || !uuid) return FSL_RC_MISUSE;
else if(!fsl_is_uuid(uuid)) return FSL_RC_RANGE;
else if(!uuidLen) return FSL_RC_RANGE;
if(!db) return FSL_RC_NOT_A_REPO;
if( fsl_uuid_is_shunned(f, uuid) ){
return fsl_cx_err_set(f, FSL_RC_ACCESS,
"UUID is shunned: %s", uuid)
/* need new error code? */;
}
rc = fsl_db_transaction_begin(db);
if(rc) return rc;
rc = fsl_db_prepare_cached(db, &s1,
"INSERT INTO blob(rcvid,size,uuid,content)"
"VALUES(0,-1,?,NULL)");
if(rc) goto end;
rc = fsl_stmt_bind_text(s1, 1, uuid, FSL_UUID_STRLEN, 0);
rc = fsl_stmt_bind_text(s1, 1, uuid, uuidLen, 0);
if(!rc) rc = fsl_stmt_step(s1);
fsl_stmt_cached_yield(s1);
if(FSL_RC_STEP_DONE!=rc) goto end;
else rc = 0;
rid = fsl_db_last_insert_id(db);
assert(rid>0);
rc = fsl_db_prepare_cached(db, &s2,
|
︙ | | |
1306
1307
1308
1309
1310
1311
1312
1313
1314
|
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
|
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
assert(0==fbuf->used);
fsl_buffer_reset(nbuf);
fsl_buffer_reset(canon);
if(rc && inTrans) fsl_db_transaction_rollback(db);
return rc;
}
fsl_hash_types_t fsl_validate_hash(const char *zHash, int nHash){
/* fossil(1) counterpart: hname_validate() */
fsl_hash_types_t rc;
switch(nHash){
case FSL_UUIDv1_STRLEN: rc = FSL_HTYPE_SHA1; break;
case FSL_UUIDv2_STRLEN: rc = FSL_HTYPE_K256; break;
default: return FSL_HTYPE_ERROR;
}
return fsl_validate16(zHash, (fsl_size_t)nHash) ? rc : FSL_HTYPE_ERROR;
}
const char * fsl_hash_type_name(fsl_hash_types_t h, const char *zUnknown){
/* fossil(1) counterpart: hname_alg() */
switch(h){
case FSL_HTYPE_SHA1: return "SHA1";
case FSL_HTYPE_K256: return "SHA3-256";
default: return zUnknown;
}
}
fsl_hash_types_t fsl_verify_blob_hash(fsl_buffer const * pIn,
const char *zHash, int nHash){
fsl_hash_types_t id = FSL_HTYPE_ERROR;
switch(nHash){
case FSL_UUIDv1_STRLEN:{
fsl_sha1_cx cx;
char hex[FSL_UUIDv1_STRLEN+1] = {0};
fsl_sha1_init(&cx);
fsl_sha1_update(&cx, pIn->mem, (unsigned)pIn->used);
fsl_sha1_final_hex(&cx, hex);
if(0==memcmp(hex, zHash, FSL_UUIDv1_STRLEN)){
id = FSL_HTYPE_SHA1;
}
break;
}
case FSL_UUIDv2_STRLEN:{
fsl_sha3_cx cx;
unsigned char const * hex;
fsl_sha3_init(&cx);
fsl_sha3_update(&cx, pIn->mem, (unsigned)pIn->used);
hex = fsl_sha3_end(&cx);
if(0==memcmp(hex, zHash, FSL_UUIDv2_STRLEN)){
id = FSL_HTYPE_K256;
}
break;
}
default:
break;
}
return id;
}
#undef MARKER
|
︙ | | |
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
+
+
-
-
+
+
-
+
-
+
|
fsl_free(t);
}
}
fsl_card_Q * fsl_card_Q_malloc(int type,
fsl_uuid_cstr target,
fsl_uuid_cstr baseline){
int const targetLen = target ? fsl_is_uuid(target) : 0;
int const baselineLen = baseline ? fsl_is_uuid(baseline) : 0;
if(!type || !target || !fsl_is_uuid(target)
|| (baseline && !fsl_is_uuid(baseline))) return NULL;
if(!type || !target || !targetLen
|| (baseline && !baselineLen)) return NULL;
else{
fsl_card_Q * c =
(fsl_card_Q*)fsl_malloc(sizeof(fsl_card_Q));
if(c){
int rc = 0;
*c = fsl_card_Q_empty;
c->type = type;
c->target = fsl_strndup(target, FSL_UUID_STRLEN);
c->target = fsl_strndup(target, targetLen);
if(!c->target) rc = FSL_RC_OOM;
else if(baseline){
c->baseline = fsl_strndup( baseline, FSL_UUID_STRLEN);
c->baseline = fsl_strndup(baseline, baselineLen);
if(!c->baseline) rc = FSL_RC_OOM;
}
if(rc){
fsl_card_Q_free(c);
c = NULL;
}
}
|
︙ | | |
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
+
-
+
-
-
+
+
|
}
fsl_card_F * fsl_card_F_malloc(char const * name,
char const * uuid,
fsl_file_perm_t perm,
char const * oldName){
fsl_card_F * t;
int const uLen = uuid ? fsl_is_uuid(uuid) : 0;
if(!name || !*name) return NULL;
else if(uuid && !fsl_is_uuid(uuid)) return NULL;
else if(uuid && !uLen) return NULL;
t = (fsl_card_F *)fsl_malloc(sizeof(fsl_card_F));
if(t){
int rc = 0;
*t = fsl_card_F_empty;
t->perm = perm;
t->name = fsl_strdup(name);
if(!t->name) rc = FSL_RC_OOM;
if(!rc && uuid){
t->uuid = fsl_strdup(uuid);
if(!rc && uLen){
t->uuid = fsl_strndup(uuid, uLen);
if(!t->uuid) rc = FSL_RC_OOM;
}
if(!rc && oldName){
t->priorName = fsl_strdup(oldName);
if(!t->priorName) rc = FSL_RC_OOM;
}
if(rc){
|
︙ | | |
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
|
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
|
-
-
-
+
+
+
-
+
+
+
-
+
-
+
|
The function returns FSL_RC_RANGE if (valLen!=ASSERTLEN). ASSERTLEN
is assumed to be either an SHA1 or MD5 hash value and it is
validated against fsl_validate16(value,valLen), returning
FSL_RC_CA_SYNTAX if that check fails.
*/
static int fsl_deck_sethex_impl( fsl_deck * mf, fsl_uuid_cstr value,
char letter,
fsl_size_t assertLen,
char ** mfMember ){
char letter,
fsl_size_t assertLen,
char ** mfMember ){
assert(mf);
assert( assertLen==FSL_UUID_STRLEN || assertLen==FSL_MD5_STRLEN );
assert( assertLen==FSL_UUIDv1_STRLEN
|| assertLen==FSL_UUIDv2_STRLEN
|| assertLen==FSL_MD5_STRLEN );
if(!fsl_deck_check_type(mf,letter)) return FSL_RC_TYPE;
else if(!value){
fsl_deck_free_string(mf, *mfMember);
*mfMember = NULL;
return 0;
}else if(fsl_strlen(value) != (assertLen)){
}else if(fsl_strlen(value) != assertLen){
return fsl_error_set(&mf->error, FSL_RC_RANGE,
"Invalid length for %c-card: expecting %d.",
letter, (int)assertLen);
}else if(!fsl_validate16(value, assertLen)) {
return fsl_error_set(&mf->error, FSL_RC_CA_SYNTAX,
"Invalid hexadecimal value for %c-card.", letter);
}else{
fsl_deck_free_string(mf, *mfMember);
*mfMember = fsl_strndup( value, assertLen );
*mfMember = fsl_strndup(value, assertLen);
return *mfMember ? 0 : FSL_RC_OOM;
}
}
/**
Implements fsl_set_set_XXX() where XXX is a fsl_buffer member of fsl_deck.
*/
|
︙ | | |
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
|
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
|
+
+
+
+
+
-
+
|
return 0;
}
}
int fsl_deck_B_set( fsl_deck * mf, fsl_uuid_cstr uuidBaseline){
if(!mf) return FSL_RC_MISUSE;
else{
int const bLen = fsl_is_uuid(uuidBaseline);
if(!bLen){
return fsl_error_set(&mf->error, FSL_RC_CA_SYNTAX,
"Invalid B-card value: %s", uuidBaseline);
}
if(mf->B.baseline){
fsl_deck_finalize(mf->B.baseline);
mf->B.baseline = NULL;
}
return fsl_deck_sethex_impl(mf, uuidBaseline, 'B',
FSL_UUID_STRLEN, &mf->B.uuid);
bLen, &mf->B.uuid);
}
}
/**
Internal impl for card setters which consider of a simple (char *)
member.
*/
|
︙ | | |
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
|
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
|
+
-
-
+
+
+
-
-
+
+
|
}
return rc;
}
}
int fsl_deck_K_set( fsl_deck * mf, fsl_uuid_cstr uuid){
int const uLen = fsl_is_uuid(uuid);
return mf
? fsl_deck_sethex_impl(mf, uuid, 'K', FSL_UUID_STRLEN, &mf->K)
return (mf && uLen)
? fsl_deck_sethex_impl(mf, uuid, 'K', uLen, &mf->K)
: FSL_RC_MISUSE;
}
int fsl_deck_L_set( fsl_deck * mf, char const * v, fsl_int_t n){
return mf
? fsl_deck_set_string(mf, 'L', &mf->L, v, n)
: FSL_RC_MISUSE;
}
int fsl_deck_M_add( fsl_deck * mf, char const *uuid){
int rc;
char * dupe;
int const uLen = uuid ? fsl_is_uuid(uuid) : 0;
if(!mf || !uuid) return FSL_RC_MISUSE;
else if(!fsl_deck_check_type(mf, 'M')) return FSL_RC_TYPE;
else if(!fsl_is_uuid(uuid)) return FSL_RC_RANGE;
dupe = fsl_strndup(uuid, FSL_UUID_STRLEN);
else if(!uLen) return FSL_RC_RANGE;
dupe = fsl_strndup(uuid, uLen);
if(!dupe) rc = FSL_RC_OOM;
else{
rc = fsl_list_append( &mf->M, dupe );
if(rc){
fsl_free(dupe);
}
}
|
︙ | | |
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
|
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
|
+
-
+
-
+
|
: FSL_RC_MISUSE;
}
int fsl_deck_P_add( fsl_deck * mf, char const *parentUuid){
int rc;
char * dupe;
int const uLen = parentUuid ? fsl_is_uuid(parentUuid) : 0;
if(!mf || !parentUuid || !*parentUuid) return FSL_RC_MISUSE;
else if(!fsl_deck_check_type(mf, 'P')) return FSL_RC_TYPE;
else if(!fsl_is_uuid(parentUuid)){
else if(!uLen){
return fsl_error_set(&mf->error, FSL_RC_RANGE,
"Invalid UUID for P-card.");
}
dupe = fsl_strndup(parentUuid, FSL_UUID_STRLEN);
dupe = fsl_strndup(parentUuid, uLen);
if(!dupe) rc = FSL_RC_OOM;
else{
rc = fsl_list_append( &mf->P, dupe );
if(rc){
fsl_free(dupe);
}
}
|
︙ | | |
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
|
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
|
+
-
+
-
-
+
+
+
-
+
-
+
-
+
|
? fsl_deck_b_setuffer_impl(mf, v, n, 'W', &mf->W)
: FSL_RC_MISUSE;
}
int fsl_deck_A_set( fsl_deck * mf, char const * name,
char const * tgt,
char const * uuidSrc ){
int const uLen = (uuidSrc && *uuidSrc) ? fsl_is_uuid(uuidSrc) : 0;
if(!mf || !name || !tgt) return FSL_RC_MISUSE;
else if(!fsl_deck_check_type(mf, 'A')) return FSL_RC_TYPE;
else if(!*tgt){
return fsl_error_set(&mf->error, FSL_RC_RANGE,
"Invalid target name in A card.");
}
/* TODO: validate tgt based on mf->type and require UUID
for types EVENT/TICKET.
*/
else if(uuidSrc && *uuidSrc && !fsl_is_uuid(uuidSrc)){
else if(uuidSrc && *uuidSrc && !uLen){
return fsl_error_set(&mf->error, FSL_RC_RANGE,
"Invalid source UUID in A card.");
}
else{
int rc = 0;
fsl_deck_free_string(mf, mf->A.tgt);
fsl_deck_free_string(mf, mf->A.src);
fsl_deck_free_string(mf, mf->A.name);
mf->A.name = mf->A.src = NULL;
if(! (mf->A.tgt = fsl_strdup(tgt))) rc = FSL_RC_OOM;
else if( !(mf->A.name = fsl_strdup(name))) rc = FSL_RC_OOM;
else if(uuidSrc && *uuidSrc){
mf->A.src = fsl_strndup(uuidSrc,FSL_UUID_STRLEN);
else if(uLen){
mf->A.src = fsl_strndup(uuidSrc,uLen);
if(!mf->A.src) rc = FSL_RC_OOM
/* Leave mf->A.tgt/name for downstream cleanup. */;
}
return rc;
}
}
int fsl_deck_D_set( fsl_deck * mf, fsl_double_t date){
if(!mf) return FSL_RC_MISUSE;
else if(date<=0) return FSL_RC_RANGE;
else if(!fsl_deck_check_type(mf, 'D')) return FSL_RC_TYPE;
else{
mf->D = date;
return 0;
}
}
int fsl_deck_E_set( fsl_deck * mf, fsl_double_t date, char const * uuid){
int const uLen = uuid ? fsl_is_uuid(uuid) : 0;
if(!mf || !uuid) return FSL_RC_MISUSE;
if(!mf || !uLen) return FSL_RC_MISUSE;
else if(date<=0){
return fsl_error_set(&mf->error, FSL_RC_RANGE,
"Invalid date value for E card.");
}else if(!fsl_is_uuid(uuid)){
}else if(!uLen){
return fsl_error_set(&mf->error, FSL_RC_RANGE,
"Invalid UUID for E card.");
}
else{
mf->E.julian = date;
fsl_deck_free_string(mf, mf->E.uuid);
mf->E.uuid = fsl_strndup(uuid, FSL_UUID_STRLEN);
mf->E.uuid = fsl_strndup(uuid, uLen);
return mf->E.uuid ? 0 : FSL_RC_OOM;
}
}
int fsl_deck_F_add2( fsl_deck * mf, fsl_card_F * t){
if(!mf || !t) return FSL_RC_MISUSE;
else if(!fsl_deck_check_type(mf, 'F')) return FSL_RC_TYPE;
|
︙ | | |
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
|
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
|
+
-
+
|
}
}
int fsl_deck_F_add( fsl_deck * mf, char const * name,
char const * uuid,
fsl_file_perm_t perms,
char const * oldName){
int const uLen = uuid ? fsl_is_uuid(uuid) : 0;
if(!mf || !name) return FSL_RC_MISUSE;
else if(!fsl_deck_check_type(mf, 'F')) return FSL_RC_TYPE;
else if(!*name){
return fsl_error_set(&mf->error, FSL_RC_RANGE,
"F-card name may not be empty.");
}
else if(!fsl_is_simple_pathname(name, 1)
|| (oldName && !fsl_is_simple_pathname(oldName, 1))){
return fsl_error_set(&mf->error, FSL_RC_RANGE,
"Invalid filename for F-card (simple form required): "
"name=[%s], oldName=[%s].", name, oldName);
}
else if(uuid && !fsl_is_uuid(uuid)){
else if(uuid && !uLen){
return fsl_error_set(&mf->error, FSL_RC_RANGE,
"Invalid UUID for F-card.");
}
else {
int rc;
fsl_card_F * t;
switch(perms){
|
︙ | | |
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
|
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
|
-
-
-
+
+
-
-
-
+
|
fsl_list_visitor_f() impl for outputing P cards. obj must
be a (fsl_deck_out_state *) and obj->counter must be
set to 0 before running the visit iteration.
*/
static int fsl_list_v_mf_output_card_P(void * obj, void * visitorState ){
fsl_deck_out_state * os = (fsl_deck_out_state *)visitorState;
char const * uuid = (char const *)obj;
fsl_size_t len;
assert(uuid);
if(!fsl_is_uuid(uuid)){
int const uLen = uuid ? fsl_is_uuid(uuid) : 0;
if(!uLen){
os->rc = fsl_error_set(&os->error, FSL_RC_RANGE,
"Invalid UUID in P card.");
}
else if(!os->counter++) fsl_appendf_f_mf(os, "P ", 2);
else fsl_appendf_f_mf(os, " ", 1);
/* Reminder: fsl_appendf_f_mf() updates os->rc. */
if(!os->rc){
len = (fsl_size_t)fsl_strlen(uuid);
assert(FSL_UUID_STRLEN==len) /* is enforced by fsl_mf_add_P() */;
fsl_appendf_f_mf(os, uuid, len);
fsl_appendf_f_mf(os, uuid, (fsl_size_t)uLen);
}
return os->rc;
}
static int fsl_deck_out_P( fsl_deck_out_state * os ){
if(!fsl_deck_out_tcheck(os, 'P')) return os->rc;
|
︙ | | |
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
|
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
|
-
+
|
wiki_end:
fsl_buffer_clear(&buf);
if(rc) goto end;
}/*WIKI*/
if( d->type==FSL_CATYPE_EVENT ){
char buf[FSL_UUID_STRLEN + 7 /* event-UUID */] = {0};
char buf[FSL_UUIDv2_STRLEN + 7 /* event-UUID */] = {0};
char zLength[40] = {0};
fsl_id_t tagid;
fsl_id_t prior, subsequent;
char const * zWiki;
char const * zTag;
fsl_size_t nWiki = 0;
fsl_snprintf(buf, sizeof(buf), "event-%s", d->E.uuid);
|
︙ | | |
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
|
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
|
-
+
-
-
-
-
+
+
+
+
|
x.zEnd = z+n;
x.atEol= 1;
/* Parsing helpers... */
#define TOKEN(DEFOS) tokLen=0; token = fsl_mf_next_token(&x,&tokLen); \
if(token && tokLen && (DEFOS)) fsl_bytes_defossilize(token, &tokLen)
#define TOKEN_EXISTS(MSG_IF_NOT) if(!token){ SYNTAX(MSG_IF_NOT); }(void)0
#define TOKEN_CHECKHEX(LEN,MSG) if(token \
#define TOKEN_CHECKHEX(MSG) if(token && (int)tokLen!=fsl_is_uuid((char const *)token))\
&& ((LEN)!=tokLen || \
!fsl_validate16((char const *)token,(LEN)))){ \
SYNTAX(MSG); }
#define TOKEN_UUID(CARD) TOKEN_CHECKHEX(FSL_UUID_STRLEN,"Malformed UUID in " #CARD "-card")
{ SYNTAX(MSG); }
#define TOKEN_UUID(CARD) TOKEN_CHECKHEX("Malformed UUID in " #CARD "-card")
#define TOKEN_MD5(ERRMSG) if(!token || FSL_MD5_STRLEN!=(int)tokLen) \
{SYNTAX(ERRMSG);}
/**
Reminder: we do not know the type of the manifest at this point,
so all of the fsl_deck_add/set() bits below can't do their
validation. We have to determine at parse-time (or afterwards)
which type of deck it is based on the cards we've seen. We guess
the type as early as possible to enable during-parse validation,
and do a post-parse check for the legality of cards added before
|
︙ | | |
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
|
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
|
-
+
|
*/
case 'R':{
if(1<SEEN(R)){
ERROR(FSL_RC_RANGE,"More than one R-card");
}
TOKEN(0);
TOKEN_EXISTS("Missing MD5 token in R-card");
TOKEN_CHECKHEX(FSL_MD5_STRLEN,"Malformed MD5 token in R-card");
TOKEN_MD5("Malformed MD5 token in R-card");
d->R = (char *)token;
++stealBuf;
/* rc = fsl_deck_R_set(d, (char const *)token); */
break;
}
/*
T (+|*|-)<tagname> <uuid> ?<value>?
|
︙ | | |
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
|
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
|
-
+
|
unsigned char * name, * value;
fsl_tag_type tagType = FSL_TAGTYPE_INVALID;
TOKEN(0);
TOKEN_EXISTS("Missing name for T-card");
name = token;
TOKEN(0);
TOKEN_EXISTS("Missing UUID on T-card");
if(FSL_UUID_STRLEN==tokLen){
if(fsl_is_uuid_len((int)tokLen)){
TOKEN_UUID(T);
/* A valid UUID */
if(FSL_CATYPE_EVENT==d->type){
SYNTAX("Non-self-referential T-card in Event artifact");
}
uuid = token;
}else if( 1==tokLen && '*'==(char)*token ){
|
︙ | | |
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
|
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
|
+
+
+
+
+
+
+
|
if(rid<0){
return fsl_cx_err_set(f, FSL_RC_RANGE,
"Invalid RID for fsl_deck_load_rid(): "
"%"FSL_ID_T_PFMT, (fsl_id_t)rid);
}
rc = fsl_content_get(f, rid, &buf);
if(!rc){
#if 0
MARKER(("fsl_content_get(%d) len=%d =\n%.*s\n",
(int)rid, (int)buf.used, (int)buf.used, (char const*)buf.mem));
#endif
fsl_deck_clean(d);
fsl_deck_init(f, d, FSL_CATYPE_ANY);
#if 0
/*
If we set d->type=type, the parser can fail more
quickly. However, that failure will bypass our more specific
reporting of the problem (see below). As the type mismatch case
is expected to be fairly rare, we'll leave this out for now, but
it might be worth considering as a small optimization later on.
*/
d->type = type /* may help parsing fail more quickly if
it's not the type we want.*/;
#endif
rc = fsl_deck_parse(d, &buf);
#if 0
MARKER(("rid=%d, d->rid=%d\n", (int)rid, (int)d->rid));
#endif
if(!rc){
assert(rid == d->rid);
if( type!=FSL_CATYPE_ANY && d->type!=type ){
rc = fsl_cx_err_set(f, FSL_RC_TYPE,
"RID %"FSL_ID_T_PFMT" is of type %s, "
"but the caller requested type %s.",
(fsl_id_t)rid,
|
︙ | | |
︙ | | |
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
|
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
|
-
+
|
digest is stored in the first 20 bytes. zBuf should
be "char zBuf[41]".
*/
void fsl_sha1_digest_to_base16(unsigned char *digest, char *zBuf){
static char const zEncode[] = "0123456789abcdef";
int ix;
for(ix=0; ix<20; ix++){
for(ix=0; ix<FSL_UUIDv1_STRLEN/2; ix++){
*zBuf++ = zEncode[(*digest>>4)&0xf];
*zBuf++ = zEncode[*digest++ & 0xf];
}
*zBuf = '\0';
}
|
︙ | | |
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
|
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
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
|
+
+
+
+
+
+
+
+
-
-
-
+
-
-
+
-
+
|
digest[i] = (unsigned char)
((ctx->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
}
return 0;
#endif
}
char const * fsl_sha1_final_hex(fsl_sha1_cx *context, char * zHex){
unsigned char zResult[FSL_UUIDv1_STRLEN/2];
fsl_sha1_final(context, zResult);
fsl_sha1_digest_to_base16(zResult, zHex);
return (char const *)zHex;
}
int fsl_sha1sum_stream(fsl_input_f src, void * srcState, fsl_buffer *pCksum){
enum { BufSize = 1024 * 4 };
fsl_sha1_cx ctx;
int rc;
unsigned char zResult[20];
enum { BufSize = 1024 * 4 };
unsigned char zBuf[BufSize];
if(!src || !pCksum) return FSL_RC_MISUSE;
fsl_sha1_init(&ctx);
for(;;){
fsl_size_t read = (fsl_size_t)BufSize;
rc = src(srcState, zBuf, &read);
if(rc) return rc;
else if(read) fsl_sha1_update(&ctx, (unsigned char*)zBuf, read);
if(read < (fsl_size_t)BufSize) break;
}
fsl_buffer_reset(pCksum);
rc = fsl_buffer_resize(pCksum, FSL_UUID_STRLEN);
rc = fsl_buffer_resize(pCksum, FSL_UUIDv1_STRLEN);
if(!rc){
fsl_sha1_final(&ctx, zResult);
fsl_sha1_digest_to_base16(zResult, fsl_buffer_str(pCksum));
fsl_sha1_final_hex(&ctx, fsl_buffer_str(pCksum));
}
return rc;
}
int fsl_sha1sum_filename(const char *zFilename, fsl_buffer *pCksum){
if(!zFilename || !pCksum) return FSL_RC_MISUSE;
else{
#if 1
int rc;
FILE *in = fsl_fopen(zFilename, "rb");
if(!in) rc = FSL_RC_IO;
else{
rc = fsl_sha1sum_stream(fsl_input_f_FILE, in, pCksum);
fsl_fclose(in);
}
return rc;
#else
/* Requires v1 code which has not yet been ported in. */
FILE *in;
fsl_sha1_cx ctx;
unsigned char zResult[20];
unsigned char zResult[FSL_UUIDv1_STRLEN/2];
char zBuf[10240];
if( fsl_wd_islink(zFilename) ){
/* Instead of file content, return sha1 of link destination path */
Blob destinationPath;
int rc;
|
︙ | | |
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
1912
1913
1914
1915
1916
|
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
1912
1913
1914
1915
1916
1917
|
-
+
-
-
+
-
-
+
-
-
-
+
+
-
+
-
-
+
|
int n;
n = fread(zBuf, 1, sizeof(zBuf), in);
if( n<=0 ) break;
fsl_sha1_update(&ctx, (unsigned char*)zBuf, (unsigned)n);
}
fclose_fclose(in);
blob_zero(pCksum);
blob_resize(pCksum, FSL_UUID_STRLEN);
blob_resize(pCksum, FSL_UUIDv1_STRLEN);
fsl_sha1_final(&ctx, zResult);
fsl_sha1_digest_to_base16(zResult, blob_buffer(pCksum));
return 0;
#endif
}
}
int fsl_sha1sum_buffer(fsl_buffer const *pIn, fsl_buffer *pCksum){
if(!pIn || !pCksum) return FSL_RC_MISUSE;
else{
fsl_sha1_cx ctx;
unsigned char zResult[20];
int rc;
fsl_sha1_init(&ctx);
fsl_sha1_update(&ctx, pIn->mem, pIn->used);
fsl_buffer_reset(pCksum);
rc = fsl_buffer_resize(pCksum, FSL_UUID_STRLEN
rc = fsl_buffer_resize(pCksum, FSL_UUIDv1_STRLEN
/*resize() adds 1 for NUL*/);
if(!rc){
fsl_sha1_final(&ctx, zResult);
fsl_sha1_digest_to_base16(zResult, fsl_buffer_str(pCksum));
fsl_sha1_final_hex(&ctx, fsl_buffer_str(pCksum));
assert(0==pCksum->mem[pCksum->used]);
}
return rc;
}
}
char *fsl_sha1sum_cstr(const char *zIn, fsl_int_t len){
if(!zIn || !len) return NULL;
else{
fsl_sha1_cx ctx;
unsigned char zResult[20];
char * zDigest = (char *)fsl_malloc(FSL_UUID_STRLEN+1);
if(!zDigest) return NULL;
char * zHex = (char *)fsl_malloc(FSL_UUIDv1_STRLEN+1);
if(!zHex) return NULL;
fsl_sha1_init(&ctx);
fsl_sha1_update(&ctx, zIn,
(len<0) ? fsl_strlen(zIn) : (fsl_size_t)len);
fsl_sha1_final(&ctx, zResult);
fsl_sha1_final_hex(&ctx, zHex);
fsl_sha1_digest_to_base16(zResult, zDigest);
return zDigest;
return zHex;
}
}
|
︙ | | |
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
+
+
+
+
+
+
+
+
|
#include "fossil-scm/fossil-hash.h"
#include <assert.h>
#include <string.h> /* strlen() */
#include <stddef.h> /* NULL on linux */
#include <sys/types.h>
#include <assert.h>
#if 0
#include <stdio.h>
#define MARKER(pfexp) \
do{ printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); \
printf pfexp; \
} while(0)
#endif
/*
** Macros to determine whether the machine is big or little endian,
** and whether or not that determination is run-time or compile-time.
**
** For best performance, an attempt is made to guess at the byte-order
** using C-preprocessor macros. If that is unsuccessful, or if
** -DSHA3_BYTEORDER=0 is set, then byte-order is determined
|
︙ | | |
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
|
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
|
-
+
+
+
+
+
|
case 384: return FSL_SHA3_384; case 416: return FSL_SHA3_416;
case 448: return FSL_SHA3_448; case 480: return FSL_SHA3_480;
case 512: return FSL_SHA3_512;
default: return FSL_SHA3_INVALID;
}
}
void fsl_sha3_init(fsl_sha3_cx *p, enum fsl_sha3_hash_size iSize){
void fsl_sha3_init(fsl_sha3_cx *cx){
fsl_sha3_init2(cx, FSL_SHA3_DEFAULT);
}
void fsl_sha3_init2(fsl_sha3_cx *p, enum fsl_sha3_hash_size iSize){
assert(iSize>0);
memset(p, 0, sizeof(*p));
p->size = iSize;
if( iSize>=128 && iSize<=512 ){
p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
}else{
p->nRate = (1600 - 2*256)/8;
}
|
︙ | | |
505
506
507
508
509
510
511
512
513
|
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
|
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
p->u.x[i+p->nRate] = p->u.x[i^p->ixMask];
}
DigestToBase16( &p->u.x[p->nRate], p->hex, (int)p->size/8 );
assert(0 == p->hex[(int)p->size/4+1]);
return &p->u.x[p->nRate];
}
void fsl_sha3_digest_to_base16(unsigned char *digest, char *zBuf){
static char const zEncode[] = "0123456789abcdef";
int ix;
for(ix=0; ix<FSL_UUIDv2_STRLEN/2; ix++){
*zBuf++ = zEncode[(*digest>>4)&0xf];
*zBuf++ = zEncode[*digest++ & 0xf];
}
*zBuf = '\0';
}
int fsl_sha3sum_stream(fsl_input_f src, void * srcState, fsl_buffer *pCksum){
fsl_sha3_cx ctx;
int rc;
enum { BufSize = 1024 * 4 };
unsigned char zBuf[BufSize];
if(!src || !pCksum) return FSL_RC_MISUSE;
fsl_sha3_init(&ctx);
for(;;){
fsl_size_t read = (fsl_size_t)BufSize;
rc = src(srcState, zBuf, &read);
if(rc) return rc;
else if(read) fsl_sha3_update(&ctx, (unsigned char*)zBuf, read);
if(read < (fsl_size_t)BufSize) break;
}
fsl_buffer_reset(pCksum);
rc = fsl_buffer_resize(pCksum, FSL_UUIDv2_STRLEN);
if(!rc){
fsl_sha3_end(&ctx);
rc = fsl_buffer_append(pCksum, ctx.hex, fsl_strlen((const char *)ctx.hex));
}
return rc;
}
int fsl_sha3sum_buffer(fsl_buffer const *pIn, fsl_buffer *pCksum){
if(!pIn || !pCksum) return FSL_RC_MISUSE;
else{
fsl_sha3_cx ctx;
int rc;
fsl_sha3_init(&ctx);
fsl_sha3_update(&ctx, pIn->mem, pIn->used);
fsl_buffer_reset(pCksum);
rc = fsl_buffer_resize(pCksum, FSL_UUIDv2_STRLEN
/*resize() adds 1 for NUL*/);
if(!rc){
pCksum->used = 0;
fsl_sha3_end(&ctx);
assert(fsl_strlen((char const*)ctx.hex)==FSL_UUIDv2_STRLEN);
rc = fsl_buffer_append(pCksum, ctx.hex, fsl_strlen((char const*)ctx.hex));
assert(!rc && "Cannot fail - pre-allocated");
if(!rc){
assert(0==pCksum->mem[pCksum->used]);
}
}
return rc;
}
}
char *fsl_sha3sum_cstr(const char *zIn, fsl_int_t len){
if(!zIn || !len) return NULL;
else{
fsl_sha3_cx ctx;
fsl_sha3_init(&ctx);
fsl_sha3_update(&ctx, zIn,
(len<0) ? fsl_strlen(zIn) : (fsl_size_t)len);
fsl_sha3_end(&ctx);
return fsl_strdup((char const *)ctx.hex);
}
}
int fsl_sha3sum_filename(const char *zFilename, fsl_buffer *pCksum){
if(!zFilename || !pCksum) return FSL_RC_MISUSE;
else{
#if 1
int rc;
FILE *in = fsl_fopen(zFilename, "rb");
if(!in) rc = FSL_RC_IO;
else{
rc = fsl_sha3sum_stream(fsl_input_f_FILE, in, pCksum);
fsl_fclose(in);
}
return rc;
#else
/* Requires v1 code which has not yet been ported in. */
FILE *in;
fsl_sha1_cx ctx;
char zBuf[10240];
int rc;
if( fsl_wd_islink(zFilename) ){
/* Instead of file content, return sha3 of link destination path */
Blob destinationPath;
blob_read_link(&destinationPath, zFilename);
rc = fsl_sha3sum_buffer(&destinationPath, pCksum);
fsl_buffer_clear(&destinationPath);
return rc;
}
in = fossil_fopen(zFilename,"rb");
if( in==0 ){
return 1;
}
fsl_sha3_init(&ctx);
for(;;){
int n;
n = fread(zBuf, 1, sizeof(zBuf), in);
if( n<=0 ) break;
fsl_sha3_update(&ctx, (unsigned char*)zBuf, (unsigned)n);
}
fclose_fclose(in);
blob_zero(pCksum);
blob_resize(pCksum, FSL_UUIDv1_STRLEN);
fsl_sha3_end(&ctx);
rc = fsl_buffer_append(pCksum, ctx.hex, fsl_strlen(ctx.hex));
return rc;
#endif
}
}
#undef SHA3_BYTEORDER
#undef MARKER
|
︙ | | |
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
-
+
|
if(rc) goto end;
rc = fsl_stmt_bind_id_name(&qIns, ":vid", vid);
while( !rc && !(rc=fsl_deck_F_next(&d, &fc)) && fc){
fsl_id_t rid;
fsl_int64_t size;
if(!fc->uuid /* was removed in this version */
|| fsl_uuid_is_shunned(f,fc->uuid)) continue;
rc = fsl_stmt_bind_text(&qRid, 1, fc->uuid, FSL_UUID_STRLEN, 0);
rc = fsl_stmt_bind_text(&qRid, 1, fc->uuid, -1, 0);
if(rc) break;
rc = fsl_stmt_step(&qRid);
if(FSL_RC_STEP_ROW==rc){
rid = fsl_stmt_g_id(&qRid,0);
size = fsl_stmt_g_int64(&qRid,1);
}else if(FSL_RC_STEP_DONE==rc){
rid = 0;
|
︙ | | |
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
else rc = fsl_db_transaction_commit(dbC);
if(rc && !f->error.code){
if(dbC->error.code) fsl_cx_uplift_db_error(f, dbC);
else if(dbR->error.code) fsl_cx_uplift_db_error(f, dbR);
}
return rc;
}
/**
Internal code de-duplifier for places which need to re-check a
file's hash in order to be sure whether it was really
modified. hashLen must be the length of the previous (db-side)
hash of the file. This routine will hash that file using the same
hash type.
Returns 0 on success. On error, if *errReported is set to non-0 then the
error state has already been set
*/
static int fsl_vfile_recheck_file_hash( fsl_cx * f, const char * zName,
int hashLen, fsl_buffer * pTgt ){
int errReported = 0;
int rc = 0;
pTgt->used = 0;
if(FSL_UUIDv1_STRLEN==hashLen){
rc = fsl_sha1sum_filename(zName, pTgt);
}else if(FSL_UUIDv2_STRLEN==hashLen){
rc = fsl_sha3sum_filename(zName, pTgt);
}else{
rc = fsl_cx_err_set(f, FSL_RC_CHECKSUM_MISMATCH,
"Cannot determine which hash to use for file: %s",
zName);
errReported = 1;
}
if(rc && !errReported && FSL_RC_OOM != rc){
rc = fsl_cx_err_set(f, rc, "Error %s while reading SHA of file: %s",
fsl_rc_cstr(rc), zName);
}
return rc;
}
/**
UNTESTED single-file version of fsl_vfile_changes_scan().
vid is the version to scan changes against. If 0 or less, the
current checkout is used. The vfile table must have been previously
populated with vid's contents (which it will have been for the
|
︙ | | |
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
247
248
249
250
251
252
253
254
255
256
257
258
259
260
|
-
-
|
default:
assert(!rc);
goto end;
}
{
static char const * errReadingSha1 =
"Error %s while reading SHA1 of file: %s";
fsl_id_t id = fsl_stmt_g_id(q, 0);
fsl_id_t rid = fsl_stmt_g_id(q, 2);
/* fsl_size_t nName = 0; */
char const * zName = fsl_stmt_g_text(q, 1, NULL/* &nName */);
/* fsl_size_t const rootLen = fsl_strlen(f->ckout.dir); */
/* char const * relName = zName + rootLen; */
int const isDeleted = fsl_stmt_g_int32(q, 3);
|
︙ | | |
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
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
|
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
|
-
+
-
-
+
-
-
-
-
+
+
-
-
+
-
-
+
-
-
-
+
-
-
+
-
-
-
-
+
+
-
-
+
-
-
+
-
-
|
if(origSize!=currentSize){
/* A file size change is definitive - the file has changed. No
need to check the mtime or sha1sum */
changed = FSL_VFILE_CHANGE_MOD;
}else if( !forceVFileUpdate
&& changed==FSL_VFILE_CHANGE_MOD
&& rid!=0 && !isDeleted ){
/* File is believed to have changed but it is the same size.
/* File is believed to have changed but it is the same size.
Double check that it really has changed by looking at content. */
fsl_size_t nUuid = 0;
char const * uuid;
fsl_buffer * fileCksum = &f->fileContent;
assert(!fileCksum->used && "Misuse of f->fileContent.");
assert( origSize==currentSize );
fileCksum->used = 0;
rc = fsl_sha1sum_filename(zName, fileCksum);
uuid = fsl_stmt_g_text(q, 5, &nUuid);
if(rc){
if(FSL_RC_OOM != rc){
fsl_cx_err_set(f, rc, errReadingSha1,
fsl_rc_cstr(rc), zName);
assert(uuid && fsl_is_uuid(uuid)==(int)nUuid);
rc = fsl_vfile_recheck_file_hash(f, zName, (int)nUuid, fileCksum);
}
goto end;
if(rc) goto end;
}
assert(FSL_UUID_STRLEN==fileCksum->used);
assert(fsl_is_uuid_len((int)fileCksum->used));
uuid = fsl_stmt_g_text(q, 5, &nUuid);
assert(uuid && (FSL_UUID_STRLEN==nUuid));
if( 0 == fsl_uuidcmp(fsl_buffer_cstr(fileCksum), uuid) ){
changed = 0;
}
fileCksum->used = 0;
/* MARKER(("SHA1 compare says %d: %s\n", changed, zName)); */
}else if( !forceVFileUpdate
&& (changed==FSL_VFILE_CHANGE_NONE
|| changed==FSL_VFILE_CHANGE_MERGE_MOD
|| changed==FSL_VFILE_CHANGE_INTEGRATE_MOD)
&& (useMtime==0 || currentMtime!=oldMtime) ){
/* For files that were formerly believed to be unchanged or that were
changed by merging, if their mtime changes, or unconditionally
if --sha1sum is used, check to see if they have been edited by
looking at their SHA1 sum */
looking at their hash */
fsl_size_t nUuid = 0;
char const * uuid;
fsl_buffer * fileCksum = &f->fileContent;
assert(!fileCksum->used && "Misuse of f->fileContent.");
assert( origSize==currentSize );
fileCksum->used = 0;
rc = fsl_sha1sum_filename(zName, fileCksum);
uuid = fsl_stmt_g_text(q, 5, &nUuid);
if(rc){
if(FSL_RC_OOM != rc){
fsl_cx_err_set(f, rc, errReadingSha1,
fsl_rc_cstr(rc), zName);
assert(uuid && fsl_is_uuid(uuid)==(int)nUuid);
rc = fsl_vfile_recheck_file_hash(f, zName, (int)nUuid, fileCksum);
}
goto end;
if(rc) goto end;
}
assert(FSL_UUID_STRLEN==fileCksum->used);
assert(fsl_is_uuid_len((int)fileCksum->used));
uuid = fsl_stmt_g_text(q, 5, &nUuid);
assert(uuid && (FSL_UUID_STRLEN==nUuid));
if( fsl_uuidcmp(fsl_buffer_cstr(fileCksum), uuid) ){
changed = FSL_VFILE_CHANGE_MOD;
}
fileCksum->used = 0;
/* MARKER(("SHA1 compare says %d: %s\n", changed, zName)); */
}
if( (cksigFlags & FSL_VFILE_CKSIG_SETMTIME)
|
︙ | | |
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
|
421
422
423
424
425
426
427
428
429
430
431
432
433
434
|
-
-
|
fsl_db * db = fsl_needs_checkout(f);
fsl_fstat fst = fsl_fstat_empty;
fsl_deck deck = fsl_deck_empty;
#ifndef _WIN32
fsl_deck * d = NULL;
#endif
fsl_size_t rootLen;
static char const * errReadingSha1 =
"Error %s while reading SHA1 of file: %s";
if(!db) return FSL_RC_NOT_A_CHECKOUT;
assert(f->ckout.dir);
if(vid<0) vid = f->ckout.rid;
assert(vid>=0);
rootLen = fsl_strlen(f->ckout.dir);
|
︙ | | |
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
|
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
|
-
+
-
-
-
-
+
+
-
-
+
-
-
+
-
-
-
-
+
-
-
-
-
+
+
-
-
+
-
-
+
-
-
|
/* File is believed to have changed but it is the same size.
Double check that it really has changed by looking at content. */
fsl_size_t nUuid = 0;
char const * uuid;
fsl_buffer * fileCksum = &f->fileContent;
assert(!fileCksum->used && "Misuse of f->fileContent.");
assert( origSize==currentSize );
rc = fsl_sha1sum_filename(zName, fileCksum);
uuid = fsl_stmt_g_text(&q, 5, &nUuid);
if(rc){
if(FSL_RC_OOM != rc){
fsl_cx_err_set(f, rc, errReadingSha1,
fsl_rc_cstr(rc), zName);
assert(uuid && fsl_is_uuid_len((int)nUuid));
rc = fsl_vfile_recheck_file_hash(f, zName, (int)nUuid, fileCksum);
}
goto end;
if(rc) goto end;
}
assert(FSL_UUID_STRLEN==fileCksum->used);
assert(fsl_is_uuid_len((int)fileCksum->used));
uuid = fsl_stmt_g_text(&q, 5, &nUuid);
assert(uuid && (FSL_UUID_STRLEN==nUuid));
if( 0 == fsl_uuidcmp(fsl_buffer_cstr(fileCksum), uuid) ){
changed = 0;
}
fileCksum->used = 0;
/* MARKER(("SHA1 compare says %d: %s\n", changed, zName)); */
}else if( !forceVFileUpdate
&& (changed==FSL_VFILE_CHANGE_NONE
|| changed==FSL_VFILE_CHANGE_MERGE_MOD
|| changed==FSL_VFILE_CHANGE_INTEGRATE_MOD)
&& (useMtime==0 || currentMtime!=oldMtime) ){
/* For files that were formerly believed to be unchanged or that were
changed by merging, if their mtime changes, or unconditionally
if --sha1sum is used, check to see if they have been edited by
looking at their SHA1 sum */
fsl_size_t nUuid = 0;
char const * uuid;
fsl_buffer * fileCksum = &f->fileContent;
assert(!fileCksum->used && "Misuse of f->fileContent.");
assert( origSize==currentSize );
fileCksum->used = 0;
rc = fsl_sha1sum_filename(zName, fileCksum);
uuid = fsl_stmt_g_text(&q, 5, &nUuid);
if(rc){
if(FSL_RC_OOM != rc){
fsl_cx_err_set(f, rc, errReadingSha1,
fsl_rc_cstr(rc), zName);
assert(uuid && fsl_is_uuid_len((int)nUuid));
rc = fsl_vfile_recheck_file_hash(f, zName, (int)nUuid, fileCksum);
}
goto end;
if(rc) goto end;
}
assert(FSL_UUID_STRLEN==fileCksum->used);
assert(fsl_is_uuid_len((int)fileCksum->used));
uuid = fsl_stmt_g_text(&q, 5, &nUuid);
assert(uuid && (FSL_UUID_STRLEN==nUuid));
if( fsl_uuidcmp(fsl_buffer_cstr(fileCksum), uuid) ){
changed = FSL_VFILE_CHANGE_MOD;
}
fileCksum->used = 0;
/* MARKER(("SHA1 compare says %d: %s\n", changed, zName)); */
}
if( (cksigFlags & FSL_VFILE_CKSIG_SETMTIME)
|
︙ | | |