1VMOD_STD(3) VMOD_STD(3)
2
3
4
6 vmod_std - Varnish Standard Module
7
9 import std [as name] [from "path"]
10
11 REAL random(REAL lo, REAL hi)
12
13 REAL round(REAL r)
14
15 VOID collect(HEADER hdr, STRING sep)
16
17 STRING querysort(STRING)
18
19 STRING toupper(STRING s)
20
21 STRING tolower(STRING s)
22
23 STRING strstr(STRING s1, STRING s2)
24
25 BOOL fnmatch(STRING pattern, STRING subject, BOOL pathname, BOOL noescape, BOOL period)
26
27 STRING fileread(STRING)
28
29 BLOB blobread(STRING)
30
31 BOOL file_exists(STRING path)
32
33 BOOL healthy(BACKEND be)
34
35 INT port(IP ip)
36
37 DURATION duration([STRING s], [DURATION fallback], [REAL real], [INT integer])
38
39 BYTES bytes([STRING s], [BYTES fallback], [REAL real], [INT integer])
40
41 INT integer([STRING s], [INT fallback], [BOOL bool], [BYTES bytes], [DURATION duration], [REAL real], [TIME time])
42
43 IP ip(STRING s, [IP fallback], BOOL resolve, [STRING p])
44
45 REAL real([STRING s], [REAL fallback], [INT integer], [BOOL bool], [BYTES bytes], [DURATION duration], [TIME time])
46
47 TIME time([STRING s], [TIME fallback], [REAL real], [INT integer])
48
49 STRING strftime(TIME time, STRING format)
50
51 VOID log(STRING s)
52
53 VOID syslog(INT priority, STRING s)
54
55 VOID timestamp(STRING s)
56
57 BOOL syntax(REAL)
58
59 STRING getenv(STRING name)
60
61 BOOL cache_req_body(BYTES size)
62
63 VOID late_100_continue(BOOL late)
64
65 VOID set_ip_tos(INT tos)
66
67 VOID rollback(HTTP h)
68
69 BOOL ban(STRING)
70
71 STRING ban_error()
72
73 TIME now()
74
75 DURATION timed_call(SUB)
76
77 INT real2integer(REAL r, INT fallback)
78
79 TIME real2time(REAL r, TIME fallback)
80
81 INT time2integer(TIME t, INT fallback)
82
83 REAL time2real(TIME t, REAL fallback)
84
86 vmod_std contains basic functions which are part and parcel of Varnish,
87 but which for reasons of architecture fit better in a VMOD.
88
90 REAL random(REAL lo, REAL hi)
91 Returns a random real number between lo and hi.
92
93 This function uses the "testable" random generator in varnishd which
94 enables deterministic tests to be run (See m00002.vtc). This function
95 should not be used for cryptographic applications.
96
97 Example:
98
99 set beresp.http.random-number = std.random(1, 100);
100
101 REAL round(REAL r)
102 Rounds the real r to the nearest integer, but round halfway cases away
103 from zero (see round(3)).
104
106 VOID collect(HEADER hdr, STRING sep=", )
107 Collapses multiple hdr headers into one long header. The default sepa‐
108 rator sep is the standard comma separator to use when collapsing head‐
109 ers, with an additional whitespace for pretty printing.
110
111 Care should be taken when collapsing headers. In particular collapsing
112 Set-Cookie will lead to unexpected results on the browser side.
113
114 Using hdr from obj.http triggers a VCL failure.
115
116 Examples:
117
118 std.collect(req.http.accept);
119 std.collect(req.http.cookie, "; ");
120
121 STRING querysort(STRING)
122 Sorts the query string for cache normalization purposes.
123
124 Example:
125
126 set req.url = std.querysort(req.url);
127
128 STRING toupper(STRING s)
129 Converts the string s to uppercase.
130
131 Example:
132
133 set beresp.http.scream = std.toupper("yes!");
134
135 STRING tolower(STRING s)
136 Converts the string s to lowercase.
137
138 Example:
139
140 set beresp.http.nice = std.tolower("VerY");
141
142 STRING strstr(STRING s1, STRING s2)
143 Returns a string beginning at the first occurrence of the string s2 in
144 the string s1, or an empty string if s2 is not found.
145
146 Note that the comparison is case sensitive.
147
148 Example:
149
150 if (std.strstr(req.url, req.http.restrict)) {
151 ...
152 }
153
154 This will check if the content of req.http.restrict occurs anywhere in
155 req.url.
156
157 BOOL fnmatch(STRING pattern, STRING subject, BOOL pathname, BOOL noescape,
158 BOOL period)
159 BOOL fnmatch(
160 STRING pattern,
161 STRING subject,
162 BOOL pathname=1,
163 BOOL noescape=0,
164 BOOL period=0
165 )
166
167 Shell-style pattern matching; returns true if subject matches pattern,
168 where pattern may contain wildcard characters such as * or ?.
169
170 The match is executed by the implementation of fnmatch(3) on your sys‐
171 tem. The rules for pattern matching on most systems include the follow‐
172 ing:
173
174 • * matches any sequence of characters
175
176 • ? matches a single character
177
178 • a bracket expression such as [abc] or [!0-9] is interpreted as a
179 character class according to the rules of basic regular expressions
180 (not pcre2(3) regexen), except that ! is used for character class
181 negation instead of ^.
182
183 If pathname is true, then the forward slash character / is only matched
184 literally, and never matches *, ? or a bracket expression. Otherwise, /
185 may match one of those patterns. By default, pathname is true.
186
187 If noescape is true, then the backslash character \ is matched as an
188 ordinary character. Otherwise, \ is an escape character, and matches
189 the character that follows it in the pattern. For example, \\ matches \
190 when noescape is true, and \\ when false. By default, noescape is
191 false.
192
193 If period is true, then a leading period character . only matches lit‐
194 erally, and never matches *, ? or a bracket expression. A period is
195 leading if it is the first character in subject; if pathname is also
196 true, then a period that immediately follows a / is also leading (as in
197 /.). By default, period is false.
198
199 std.fnmatch() invokes VCL failure and returns false if either of pat‐
200 tern or subject is NULL -- for example, if an unset header is speci‐
201 fied.
202
203 Examples:
204
205 # Matches URLs such as /foo/bar and /foo/baz
206 if (std.fnmatch("/foo/\*", req.url)) { ... }
207
208 # Matches URLs such as /foo/bar/baz and /foo/baz/quux
209 if (std.fnmatch("/foo/\*/\*", bereq.url)) { ... }
210
211 # Matches /foo/bar/quux, but not /foo/bar/baz/quux
212 if (std.fnmatch("/foo/\*/quux", req.url)) { ... }
213
214 # Matches /foo/bar/quux and /foo/bar/baz/quux
215 if (std.fnmatch("/foo/\*/quux", req.url, pathname=false)) { ... }
216
217 # Matches /foo/bar, /foo/car and /foo/far
218 if (std.fnmatch("/foo/?ar", req.url)) { ... }
219
220 # Matches /foo/ followed by a non-digit
221 if (std.fnmatch("/foo/[!0-9]", req.url)) { ... }
222
224 STRING fileread(STRING)
225 Reads a text file and returns a string with the content.
226
227 The entire file is cached on the first call, and subsequent calls will
228 return this cached contents, even if the file has changed in the mean‐
229 time.
230
231 For binary files, use std.blobread() instead.
232
233 Example:
234
235 synthetic("Response was served by " + std.fileread("/etc/hostname"));
236
237 Consider that the entire contents of the file appear in the string that
238 is returned, including newlines that may result in invalid headers if
239 std.fileread() is used to form a header. In that case, you may need to
240 modify the string, for example with regsub() (see vcl(7)):
241
242 set beresp.http.served-by = regsub(std.fileread("/etc/hostname"), "\R$", "");
243
244 BLOB blobread(STRING)
245 Reads any file and returns a blob with the content.
246
247 The entire file is cached on the first call, and subsequent calls will
248 return this cached contents, even if the file has changed in the mean‐
249 time.
250
251 BOOL file_exists(STRING path)
252 Returns true if path or the file pointed to by path exists, false oth‐
253 erwise.
254
255 Example:
256
257 if (std.file_exists("/etc/return_503")) {
258 return (synth(503, "Varnish is in maintenance"));
259 }
260
262 BOOL healthy(BACKEND be)
263 Returns true if the backend be is healthy.
264
265 INT port(IP ip)
266 Returns the port number of the IP address ip. Always returns 0 for a
267 *.ip variable when the address is a Unix domain socket.
268
270 These functions all have the same form:
271
272 TYPE type([arguments], [fallback TYPE])
273
274 Precisely one of the arguments must be provided (besides the optional
275 fallback), and it will be converted to TYPE.
276
277 If conversion fails, fallback will be returned and if no fallback was
278 specified, the VCL will be failed.
279
280 DURATION duration([STRING s], [DURATION fallback], [REAL real], [INT inte‐
281 ger])
282 DURATION duration(
283 [STRING s],
284 [DURATION fallback],
285 [REAL real],
286 [INT integer]
287 )
288
289 Returns a DURATION from a STRING, REAL or INT argument.
290
291 For a STRING s argument, s must be quantified by ms (milliseconds), s
292 (seconds), m (minutes), h (hours),``d`` (days), w (weeks) or y (years)
293 units.
294
295 real and integer arguments are taken as seconds.
296
297 If the conversion of an s argument fails, fallback will be returned if
298 provided, or a VCL failure will be triggered.
299
300 Conversions from real and integer arguments never fail.
301
302 Only one of the s, real or integer arguments may be given or a VCL
303 failure will be triggered.
304
305 Examples:
306
307 set beresp.ttl = std.duration("1w", 3600s);
308 set beresp.ttl = std.duration(real=1.5);
309 set beresp.ttl = std.duration(integer=10);
310
311 BYTES bytes([STRING s], [BYTES fallback], [REAL real], [INT integer])
312 BYTES bytes(
313 [STRING s],
314 [BYTES fallback],
315 [REAL real],
316 [INT integer]
317 )
318
319 Returns BYTES from a STRING, REAL or INT argument.
320
321 A STRING s argument can be quantified with a multiplier (k (kilo), m
322 (mega), g (giga), t (tera) or p (peta)).
323
324 real and integer arguments are taken as bytes.
325
326 If the conversion of an s argument fails, fallback will be returned if
327 provided, or a VCL failure will be triggered.
328
329 Other conversions may fail if the argument can not be represented, be‐
330 cause it is negative, too small or too large. Again, fallback will be
331 returned if provided, or a VCL failure will be triggered.
332
333 real arguments will be rounded down.
334
335 Only one of the s, real or integer arguments may be given or a VCL
336 failure will be triggered.
337
338 Example:
339
340 std.cache_req_body(std.bytes(something.somewhere, 10K));
341 std.cache_req_body(std.bytes(integer=10*1024));
342 std.cache_req_body(std.bytes(real=10.0*1024));
343
344 INT integer([STRING s], [INT fallback], [BOOL bool], [BYTES bytes], [DURA‐
345 TION duration], [REAL real], [TIME time])
346 INT integer(
347 [STRING s],
348 [INT fallback],
349 [BOOL bool],
350 [BYTES bytes],
351 [DURATION duration],
352 [REAL real],
353 [TIME time]
354 )
355
356 Returns an INT from a STRING, BOOL or other quantity.
357
358 If the conversion of an s argument fails, fallback will be returned if
359 provided, or a VCL failure will be triggered.
360
361 A bool argument will be returned as 0 for false and 1 for true. This
362 conversion will never fail.
363
364 For a bytes argument, the number of bytes will be returned. This con‐
365 version will never fail.
366
367 A duration argument will be rounded down to the number of seconds and
368 returned.
369
370 A real argument will be rounded down and returned.
371
372 For a time argument, the number of seconds since the UNIX epoch
373 (1970-01-01 00:00:00 UTC) will be returned.
374
375 duration, real and time conversions may fail if the argument can not be
376 represented because it is too small or too large. If so, fallback will
377 be returned if provided, or a VCL failure will be triggered.
378
379 Only one of the s, bool, bytes, duration, real or time arguments may be
380 given or a VCL failure will be triggered.
381
382 Examples:
383
384 if (std.integer(req.http.foo, 0) > 5) {
385 ...
386 }
387
388 set resp.http.answer = std.integer(real=126.42/3);
389
390 IP ip(STRING s, [IP fallback], BOOL resolve=1, [STRING p])
391 Converts the string s to the first IP number returned by the system li‐
392 brary function getaddrinfo(3). If conversion fails, fallback will be
393 returned or VCL failure will happen.
394
395 The IP address includes a port number that can be found with std.port()
396 that defaults to 80. The default port can be set to a different value
397 with the p argument. It will be overridden if s contains both an IP ad‐
398 dress and a port number or service name.
399
400 When s contains both, the syntax is either address:port or address
401 port. If the address is a numerical IPv6 address it must be enclosed
402 between brackets, for example [::1] 80 or [::1]:http. The fallback may
403 also contain both an address and a port, but its default port is always
404 80.
405
406 If resolve is false, getaddrinfo(3) is called using AI_NUMERICHOST and
407 AI_NUMERICSERV to avoid network lookups depending on the system's
408 getaddrinfo(3) or nsswitch configuration. This makes "numerical" IP
409 strings and services cheaper to convert.
410
411 Example:
412
413 if (std.ip(req.http.X-forwarded-for, "0.0.0.0") ~ my_acl) {
414 ...
415 }
416
417 REAL real([STRING s], [REAL fallback], [INT integer], [BOOL bool], [BYTES
418 bytes], [DURATION duration], [TIME time])
419 REAL real(
420 [STRING s],
421 [REAL fallback],
422 [INT integer],
423 [BOOL bool],
424 [BYTES bytes],
425 [DURATION duration],
426 [TIME time]
427 )
428
429 Returns a REAL from a STRING, BOOL or other quantity.
430
431 If the conversion of an s argument fails, fallback will be returned if
432 provided, or a VCL failure will be triggered.
433
434 A bool argument will be returned as 0.0 for false and 1.0 for true.
435
436 For a bytes argument, the number of bytes will be returned.
437
438 For a duration argument, the number of seconds will be returned.
439
440 An integer argument will be returned as a REAL.
441
442 For a time argument, the number of seconds since the UNIX epoch
443 (1970-01-01 00:00:00 UTC) will be returned.
444
445 None of these conversions other than s will fail.
446
447 Only one of the s, integer, bool, bytes, duration or time arguments may
448 be given or a VCL failure will be triggered.
449
450 Example:
451
452 if (std.real(req.http.foo, 0.0) > 5.5) {
453 ...
454 }
455
456 TIME time([STRING s], [TIME fallback], [REAL real], [INT integer])
457 TIME time([STRING s], [TIME fallback], [REAL real], [INT integer])
458
459 Returns a TIME from a STRING, REAL or INT argument.
460
461 For a STRING s argument, the following formats are supported:
462
463 "Sun, 06 Nov 1994 08:49:37 GMT"
464 "Sunday, 06-Nov-94 08:49:37 GMT"
465 "Sun Nov 6 08:49:37 1994"
466 "1994-11-06T08:49:37"
467 "784111777.00"
468 "784111777"
469
470 real and integer arguments are taken as seconds since the epoch.
471
472 If the conversion of an s argument fails or a negative real or integer
473 argument is given, fallback will be returned if provided, or a VCL
474 failure will be triggered.
475
476 Examples:
477
478 if (std.time(resp.http.last-modified, now) < now - 1w) {
479 ...
480 }
481
482 if (std.time(int=2147483647) < now - 1w) {
483 ...
484 }
485
486 STRING strftime(TIME time, STRING format)
487 Format the time argument with the format argument using strftime(3) and
488 return the result for the UTC (historically GMT) timezone.
489
490 The empty string is returned if formatting fails, but may also be re‐
491 turned as a valid result.
492
493 Example:
494
495 set req.http.iso = std.strftime(now, "%Y%m%dT%H%M%SZ");
496 # e.g. 20210521T175241Z
497
499 VOID log(STRING s)
500 Logs the string s to the shared memory log, using vsl(7) tag
501 SLT_VCL_Log.
502
503 Example:
504
505 std.log("Something fishy is going on with the vhost " + req.http.host);
506
507 VOID syslog(INT priority, STRING s)
508 Logs the string s to syslog tagged with priority. priority is formed by
509 ORing the facility and level values. See your system's syslog.h file
510 for possible values.
511
512 Notice: Unlike VCL and other functions in the std vmod, this function
513 will not fail VCL processing for workspace overflows: For an out of
514 workspace condition, the std.syslog() function has no effect.
515
516 Example:
517
518 std.syslog(9, "Something is wrong");
519
520 This will send a message to syslog using LOG_USER | LOG_ALERT.
521
522 VOID timestamp(STRING s)
523 Introduces a timestamp in the log with the current time, using the
524 string s as the label. This is useful to time the execution of lengthy
525 VCL subroutines, and makes the timestamps inserted automatically by
526 Varnish more accurate.
527
528 Example:
529
530 std.timestamp("curl-request");
531
533 BOOL syntax(REAL)
534 Returns true if VCL version is at least REAL.
535
536 STRING getenv(STRING name)
537 Return environment variable name or the empty string. See getenv(3).
538
539 Example:
540
541 set req.http.My-Env = std.getenv("MY_ENV");
542
543 BOOL cache_req_body(BYTES size)
544 Caches the request body if it is smaller than size. Returns true if
545 the body was cached, false otherwise.
546
547 Normally the request body can only be sent once. Caching it enables
548 retrying backend requests with a request body, as usually the case with
549 POST and PUT.
550
551 Example:
552
553 if (std.cache_req_body(1KB)) {
554 ...
555 }
556
557 VOID late_100_continue(BOOL late)
558 Controls when varnish reacts to an Expect: 100-continue client request
559 header.
560
561 Varnish always generates a 100 Continue response if requested by the
562 client trough the Expect: 100-continue header when waiting for request
563 body data.
564
565 But, by default, the 100 Continue response is already generated immedi‐
566 ately after vcl_recv returns to reduce latencies under the assumption
567 that the request body will be read eventually.
568
569 Calling std.late_100_continue(true) in vcl_recv will cause the 100 Con‐
570 tinue response to only be sent when needed. This may cause additional
571 latencies for processing request bodies, but is the correct behavior by
572 strict interpretation of RFC7231.
573
574 This function has no effect outside vcl_recv and after calling
575 std.cache_req_body() or any other function consuming the request body.
576
577 Example:
578
579 vcl_recv {
580 std.late_100_continue(true);
581
582 if (req.method == "POST") {
583 std.late_100_continue(false);
584 return (pass);
585 }
586 ...
587 }
588
589 VOID set_ip_tos(INT tos)
590 Sets the Differentiated Services Codepoint (DSCP) / IPv4 Type of Ser‐
591 vice (TOS) / IPv6 Traffic Class (TCLASS) byte for the current session
592 to tos. Silently ignored if the listen address is a Unix domain socket.
593
594 Please note that setting the traffic class affects all requests on the
595 same http1.1 / http2 TCP connection and, in particular, is not removed
596 at the end of the request.
597
598 Example:
599
600 if (req.url ~ "^/slow/") {
601 std.set_ip_tos(0);
602 }
603
604 VOID rollback(HTTP h)
605 Restores the h HTTP headers to their original state.
606
607 Example:
608
609 std.rollback(bereq);
610
611 BOOL ban(STRING)
612 Invalidates all objects in cache that match the given expression with
613 the ban mechanism. Returns true if the ban succeeded and false other‐
614 wise. Error details are available via std.ban_error().
615
616 The format of STRING is:
617
618 <field> <operator> <arg> [&& <field> <oper> <arg> ...]
619
620 • <field>:
621
622 • string fields:
623
624 • req.url: The request url
625
626 • req.http.*: Any request header
627
628 • obj.status: The cache object status
629
630 • obj.http.*: Any cache object header
631
632 obj.status is treated as a string despite the fact that it is actu‐
633 ally an integer.
634
635 • duration fields:
636
637 • obj.ttl: Remaining ttl at the time the ban is issued
638
639 • obj.age: Object age at the time the ban is issued
640
641 • obj.grace: The grace time of the object
642
643 • obj.keep: The keep time of the object
644
645 • <operator>:
646
647 • for all fields:
648
649 • ==: <field> and <arg> are equal
650
651 • !=: <field> and <arg> are unequal
652
653 strings are compared case sensitively
654
655 • for string fields:
656
657 • ~: <field> matches the regular expression <arg>
658
659 • !~:<field> does not match the regular expression <arg>
660
661 • for duration fields:
662
663 • >: <field> is greater than <arg>
664
665 • >=: <field> is greater than or equal to <arg>
666
667 • <: <field> is less than <arg>
668
669 • <=: <field> is less than or equal to <arg>
670
671 • <arg>:
672
673 • for string fields:
674
675 Either a literal string or a regular expression. Note that <arg>
676 does not use any of the string delimiters like " or {"..."} or
677 """...""" used elsewhere in varnish. To match against strings con‐
678 taining whitespace, regular expressions containing \s can be used.
679
680 • for duration fields:
681
682 A VCL duration like 10s, 5m or 1h, see vcl(7)_durations
683
684 Expressions can be chained using the and operator &&. For or semantics,
685 use several bans.
686
687 The unset <field> is not equal to any string, such that, for a non-ex‐
688 isting header, the operators == and ~ always evaluate as false, while
689 the operators != and !~ always evaluate as true, respectively, for any
690 value of <arg>.
691
692 STRING ban_error()
693 Returns a textual error description of the last std.ban() call from the
694 same task or the empty string if there either was no error or no
695 std.ban() call.
696
697 TIME now()
698 Returns the current time. In contrast to the now built-in variable, ev‐
699 ery call returns a new value.
700
701 DURATION timed_call(SUB)
702 Call the given SUB and return a high precision measurement of the exe‐
703 cution time.
704
706 INT real2integer(REAL r, INT fallback)
707 DEPRECATED: This function will be removed in a future version of var‐
708 nish, use std.integer() with a real argument and the std.round() func‐
709 tion instead, for example:
710
711 std.integer(real=std.round(...), fallback=...)
712
713 Rounds the real r to the nearest integer, but round halfway cases away
714 from zero (see round(3)). If conversion fails, fallback will be re‐
715 turned.
716
717 Examples:
718
719 set req.http.integer = std.real2integer(1140618699.00, 0);
720 set req.http.posone = real2integer( 0.5, 0); # = 1.0
721 set req.http.negone = real2integer(-0.5, 0); # = -1.0
722
723 TIME real2time(REAL r, TIME fallback)
724 DEPRECATED: This function will be removed in a future version of var‐
725 nish, use std.time() with a real argument and the std.round() function
726 instead, for example:
727
728 std.time(real=std.round(...), fallback=...)
729
730 Rounds the real r to the nearest integer (see std.real2integer()) and
731 returns the corresponding time when interpreted as a unix epoch. If
732 conversion fails, fallback will be returned.
733
734 Example:
735
736 set req.http.time = std.real2time(1140618699.00, now);
737
738 INT time2integer(TIME t, INT fallback)
739 DEPRECATED: This function will be removed in a future version of var‐
740 nish, use std.integer() with a time argument instead, for example:
741
742 std.integer(time=..., fallback=...)
743
744 Converts the time t to a integer. If conversion fails, fallback will be
745 returned.
746
747 Example:
748
749 set req.http.int = std.time2integer(now, 0);
750
751 REAL time2real(TIME t, REAL fallback)
752 DEPRECATED: This function will be removed in a future version of var‐
753 nish, use std.real() with a time argument instead, for example:
754
755 std.real(time=..., fallback=...)
756
757 Converts the time t to a real. If conversion fails, fallback will be
758 returned.
759
760 Example:
761
762 set req.http.real = std.time2real(now, 1.0);
763
765 • varnishd(1)
766
767 • vsl(7)
768
769 • fnmatch(3)
770
771 • strftime(3)
772
774 Copyright (c) 2010-2017 Varnish Software AS
775 All rights reserved.
776
777 Author: Poul-Henning Kamp <phk@FreeBSD.org>
778
779 SPDX-License-Identifier: BSD-2-Clause
780
781 Redistribution and use in source and binary forms, with or without
782 modification, are permitted provided that the following conditions
783 are met:
784 1. Redistributions of source code must retain the above copyright
785 notice, this list of conditions and the following disclaimer.
786 2. Redistributions in binary form must reproduce the above copyright
787 notice, this list of conditions and the following disclaimer in the
788 documentation and/or other materials provided with the distribution.
789
790 THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
791 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
792 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
793 ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
794 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
795 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
796 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
797 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
798 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
799 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
800 SUCH DAMAGE.
801
802
803
804
805 VMOD_STD(3)