]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - share/man/man9/sbuf.9
Merge bmake-20200517
[FreeBSD/FreeBSD.git] / share / man / man9 / sbuf.9
1 .\"-
2 .\" Copyright (c) 2000 Poul-Henning Kamp and Dag-Erling Coïdan Smørgrav
3 .\" All rights reserved.
4 .\"
5 .\" Redistribution and use in source and binary forms, with or without
6 .\" modification, are permitted provided that the following conditions
7 .\" are met:
8 .\" 1. Redistributions of source code must retain the above copyright
9 .\"    notice, this list of conditions and the following disclaimer.
10 .\" 2. Redistributions in binary form must reproduce the above copyright
11 .\"    notice, this list of conditions and the following disclaimer in the
12 .\"    documentation and/or other materials provided with the distribution.
13 .\"
14 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 .\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 .\" SUCH DAMAGE.
25 .\"
26 .\" $FreeBSD$
27 .\"
28 .Dd August 7, 2019
29 .Dt SBUF 9
30 .Os
31 .Sh NAME
32 .Nm sbuf ,
33 .Nm sbuf_new ,
34 .Nm sbuf_new_auto ,
35 .Nm sbuf_new_for_sysctl ,
36 .Nm sbuf_clear ,
37 .Nm sbuf_get_flags ,
38 .Nm sbuf_set_flags ,
39 .Nm sbuf_clear_flags ,
40 .Nm sbuf_setpos ,
41 .Nm sbuf_bcat ,
42 .Nm sbuf_bcopyin ,
43 .Nm sbuf_bcpy ,
44 .Nm sbuf_cat ,
45 .Nm sbuf_copyin ,
46 .Nm sbuf_cpy ,
47 .Nm sbuf_nl_terminate ,
48 .Nm sbuf_printf ,
49 .Nm sbuf_vprintf ,
50 .Nm sbuf_putc ,
51 .Nm sbuf_set_drain ,
52 .Nm sbuf_trim ,
53 .Nm sbuf_error ,
54 .Nm sbuf_finish ,
55 .Nm sbuf_data ,
56 .Nm sbuf_len ,
57 .Nm sbuf_done ,
58 .Nm sbuf_delete ,
59 .Nm sbuf_start_section ,
60 .Nm sbuf_end_section ,
61 .Nm sbuf_hexdump ,
62 .Nm sbuf_printf_drain ,
63 .Nm sbuf_putbuf
64 .Nd safe string composition
65 .Sh SYNOPSIS
66 .In sys/types.h
67 .In sys/sbuf.h
68 .Ft typedef int
69 .Fo (sbuf_drain_func)
70 .Fa "void *arg"
71 .Fa "const char *data"
72 .Fa "int len"
73 .Fc
74 .Pp
75 .Ft struct sbuf *
76 .Fo sbuf_new
77 .Fa "struct sbuf *s"
78 .Fa "char *buf"
79 .Fa "int length"
80 .Fa "int flags"
81 .Fc
82 .Ft struct sbuf *
83 .Fo sbuf_new_auto
84 .Fa "void"
85 .Fc
86 .Ft void
87 .Fo sbuf_clear
88 .Fa "struct sbuf *s"
89 .Fc
90 .Ft int
91 .Fo sbuf_get_flags
92 .Fa "struct sbuf *s"
93 .Fc
94 .Ft void
95 .Fo sbuf_set_flags
96 .Fa "struct sbuf *s"
97 .Fa "int flags"
98 .Fc
99 .Ft void
100 .Fo sbuf_clear_flags
101 .Fa "struct sbuf *s"
102 .Fa "int flags"
103 .Fc
104 .Ft int
105 .Fo sbuf_setpos
106 .Fa "struct sbuf *s"
107 .Fa "int pos"
108 .Fc
109 .Ft int
110 .Fo sbuf_bcat
111 .Fa "struct sbuf *s"
112 .Fa "const void *buf"
113 .Fa "size_t len"
114 .Fc
115 .Ft int
116 .Fo sbuf_bcpy
117 .Fa "struct sbuf *s"
118 .Fa "const void *buf"
119 .Fa "size_t len"
120 .Fc
121 .Ft int
122 .Fo sbuf_cat
123 .Fa "struct sbuf *s"
124 .Fa "const char *str"
125 .Fc
126 .Ft int
127 .Fo sbuf_cpy
128 .Fa "struct sbuf *s"
129 .Fa "const char *str"
130 .Fc
131 .Ft int
132 .Fn sbuf_nl_terminate "struct sbuf *"
133 .Ft int
134 .Fo sbuf_printf
135 .Fa "struct sbuf *s"
136 .Fa "const char *fmt" "..."
137 .Fc
138 .Ft int
139 .Fo sbuf_vprintf
140 .Fa "struct sbuf *s"
141 .Fa "const char *fmt"
142 .Fa "va_list ap"
143 .Fc
144 .Ft int
145 .Fo sbuf_putc
146 .Fa "struct sbuf *s"
147 .Fa "int c"
148 .Fc
149 .Ft void
150 .Fo sbuf_set_drain
151 .Fa "struct sbuf *s"
152 .Fa "sbuf_drain_func *func"
153 .Fa "void *arg"
154 .Fc
155 .Ft int
156 .Fo sbuf_trim
157 .Fa "struct sbuf *s"
158 .Fc
159 .Ft int
160 .Fo sbuf_error
161 .Fa "struct sbuf *s"
162 .Fc
163 .Ft int
164 .Fo sbuf_finish
165 .Fa "struct sbuf *s"
166 .Fc
167 .Ft char *
168 .Fo sbuf_data
169 .Fa "struct sbuf *s"
170 .Fc
171 .Ft ssize_t
172 .Fo sbuf_len
173 .Fa "struct sbuf *s"
174 .Fc
175 .Ft int
176 .Fo sbuf_done
177 .Fa "struct sbuf *s"
178 .Fc
179 .Ft void
180 .Fo sbuf_delete
181 .Fa "struct sbuf *s"
182 .Fc
183 .Ft void
184 .Fo sbuf_start_section
185 .Fa "struct sbuf *s"
186 .Fa "ssize_t *old_lenp"
187 .Fc
188 .Ft ssize_t
189 .Fo sbuf_end_section
190 .Fa "struct sbuf *s"
191 .Fa "ssize_t old_len"
192 .Fa "size_t pad"
193 .Fa "int c"
194 .Fc
195 .Ft void
196 .Fo sbuf_hexdump
197 .Fa "struct sbuf *sb"
198 .Fa "void *ptr"
199 .Fa "int length"
200 .Fa "const char *hdr"
201 .Fa "int flags"
202 .Fc
203 .Ft int
204 .Fo sbuf_printf_drain
205 .Fa "void *arg"
206 .Fa "const char *data"
207 .Fa "int len"
208 .Fc
209 .Ft void
210 .Fo sbuf_putbuf
211 .Fa "struct sbuf *s"
212 .Fc
213 .Fd #ifdef _KERNEL
214 .In sys/types.h
215 .In sys/sbuf.h
216 .Ft int
217 .Fo sbuf_bcopyin
218 .Fa "struct sbuf *s"
219 .Fa "const void *uaddr"
220 .Fa "size_t len"
221 .Fc
222 .Ft int
223 .Fo sbuf_copyin
224 .Fa "struct sbuf *s"
225 .Fa "const void *uaddr"
226 .Fa "size_t len"
227 .Fc
228 .In sys/sysctl.h
229 .Ft struct sbuf *
230 .Fo sbuf_new_for_sysctl
231 .Fa "struct sbuf *s"
232 .Fa "char *buf"
233 .Fa "int length"
234 .Fa "struct sysctl_req *req"
235 .Fc
236 .Fd #endif      /* _KERNEL */
237 .Sh DESCRIPTION
238 The
239 .Nm
240 family of functions allows one to safely allocate, compose and
241 release strings in kernel or user space.
242 .Pp
243 Instead of arrays of characters, these functions operate on structures
244 called
245 .Fa sbufs ,
246 defined in
247 .In sys/sbuf.h .
248 .Pp
249 Any errors encountered during the allocation or composition of the
250 string will be latched in the data structure,
251 making a single error test at the end of the composition
252 sufficient to determine success or failure of the entire process.
253 .Pp
254 The
255 .Fn sbuf_new
256 function initializes the
257 .Fa sbuf
258 pointed to by its first argument.
259 If that pointer is
260 .Dv NULL ,
261 .Fn sbuf_new
262 allocates a
263 .Vt struct sbuf
264 using
265 .Xr malloc 9 .
266 The
267 .Fa buf
268 argument is a pointer to a buffer in which to store the actual string;
269 if it is
270 .Dv NULL ,
271 .Fn sbuf_new
272 will allocate one using
273 .Xr malloc 9 .
274 The
275 .Fa length
276 is the initial size of the storage buffer.
277 The fourth argument,
278 .Fa flags ,
279 may be comprised of the following flags:
280 .Bl -tag -width ".Dv SBUF_AUTOEXTEND"
281 .It Dv SBUF_FIXEDLEN
282 The storage buffer is fixed at its initial size.
283 Attempting to extend the sbuf beyond this size results in an overflow condition.
284 .It Dv SBUF_AUTOEXTEND
285 This indicates that the storage buffer may be extended as necessary, so long
286 as resources allow, to hold additional data.
287 .It Dv SBUF_INCLUDENUL
288 This causes the final nulterm byte to be counted in the length of the data.
289 .It Dv SBUF_DRAINTOEOR
290 Treat top-level sections started with
291 .Fn sbuf_start_section
292 as a record boundary marker that will be used during drain operations to avoid
293 records being split.
294 If a record grows sufficiently large such that it fills the
295 .Fa sbuf
296 and therefore cannot be drained without being split, an error of
297 .Er EDEADLK
298 is set.
299 .It Dv SBUF_NOWAIT
300 Indicates that attempts to extend the storage buffer should fail in low memory
301 conditions, like
302 .Xr malloc 9
303 .Dv M_NOWAIT .
304 .El
305 .Pp
306 Note that if
307 .Fa buf
308 is not
309 .Dv NULL ,
310 it must point to an array of at least
311 .Fa length
312 characters.
313 The result of accessing that array directly while it is in use by the
314 sbuf is undefined.
315 .Pp
316 The
317 .Fn sbuf_new_auto
318 function is a shortcut for creating a completely dynamic
319 .Nm .
320 It is the equivalent of calling
321 .Fn sbuf_new
322 with values
323 .Dv NULL ,
324 .Dv NULL ,
325 .Dv 0 ,
326 and
327 .Dv SBUF_AUTOEXTEND .
328 .Pp
329 The
330 .Fn sbuf_new_for_sysctl
331 function will set up an sbuf with a drain function to use
332 .Fn SYSCTL_OUT
333 when the internal buffer fills.
334 Note that if the various functions which append to an sbuf are used while
335 a non-sleepable lock is held, the user buffer should be wired using
336 .Fn sysctl_wire_old_buffer .
337 .Pp
338 The
339 .Fn sbuf_delete
340 function clears the
341 .Fa sbuf
342 and frees any memory allocated for it.
343 There must be a call to
344 .Fn sbuf_delete
345 for every call to
346 .Fn sbuf_new .
347 Any attempt to access the sbuf after it has been deleted will fail.
348 .Pp
349 The
350 .Fn sbuf_clear
351 function invalidates the contents of the
352 .Fa sbuf
353 and resets its position to zero.
354 .Pp
355 The
356 .Fn sbuf_get_flags
357 function returns the current user flags.
358 The
359 .Fn sbuf_set_flags
360 and
361 .Fn sbuf_get_flags
362 functions set or clear one or more user flags, respectively.
363 The user flags are described under the
364 .Fn sbuf_new
365 function.
366 .Pp
367 The
368 .Fn sbuf_setpos
369 function sets the
370 .Fa sbuf Ns 's
371 end position to
372 .Fa pos ,
373 which is a value between zero and one less than the size of the
374 storage buffer.
375 This effectively truncates the sbuf at the new position.
376 .Pp
377 The
378 .Fn sbuf_bcat
379 function appends the first
380 .Fa len
381 bytes from the buffer
382 .Fa buf
383 to the
384 .Fa sbuf .
385 .Pp
386 The
387 .Fn sbuf_bcopyin
388 function copies
389 .Fa len
390 bytes from the specified userland address into the
391 .Fa sbuf .
392 .Pp
393 The
394 .Fn sbuf_bcpy
395 function replaces the contents of the
396 .Fa sbuf
397 with the first
398 .Fa len
399 bytes from the buffer
400 .Fa buf .
401 .Pp
402 The
403 .Fn sbuf_cat
404 function appends the NUL-terminated string
405 .Fa str
406 to the
407 .Fa sbuf
408 at the current position.
409 .Pp
410 The
411 .Fn sbuf_set_drain
412 function sets a drain function
413 .Fa func
414 for the
415 .Fa sbuf ,
416 and records a pointer
417 .Fa arg
418 to be passed to the drain on callback.
419 The drain function cannot be changed while
420 .Fa sbuf_len
421 is non-zero.
422 .Pp
423 The registered drain function
424 .Vt sbuf_drain_func
425 will be called with the argument
426 .Fa arg
427 provided to
428 .Fn sbuf_set_drain ,
429 a pointer
430 .Fa data
431 to a byte string that is the contents of the sbuf, and the length
432 .Fa len
433 of the data.
434 If the drain function exists, it will be called when the sbuf internal
435 buffer is full, or on behalf of
436 .Fn sbuf_finish .
437 The drain function may drain some or all of the data, but must drain
438 at least 1 byte.
439 The return value from the drain function, if positive, indicates how
440 many bytes were drained.
441 If negative, the return value indicates the negative error code which
442 will be returned from this or a later call to
443 .Fn sbuf_finish .
444 If the returned drained length is 0, an error of
445 .Er EDEADLK
446 is set.
447 To do unbuffered draining, initialize the sbuf with a two-byte buffer.
448 The drain will be called for every byte added to the sbuf.
449 The
450 .Fn sbuf_bcopyin ,
451 .Fn sbuf_bcpy ,
452 .Fn sbuf_clear ,
453 .Fn sbuf_copyin ,
454 .Fn sbuf_cpy ,
455 .Fn sbuf_trim ,
456 .Fn sbuf_data ,
457 and
458 .Fn sbuf_len
459 functions cannot be used on an sbuf with a drain.
460 .Pp
461 The
462 .Fn sbuf_copyin
463 function copies a NUL-terminated string from the specified userland
464 address into the
465 .Fa sbuf .
466 If the
467 .Fa len
468 argument is non-zero, no more than
469 .Fa len
470 characters (not counting the terminating NUL) are copied; otherwise
471 the entire string, or as much of it as can fit in the
472 .Fa sbuf ,
473 is copied.
474 .Pp
475 The
476 .Fn sbuf_cpy
477 function replaces the contents of the
478 .Fa sbuf
479 with those of the NUL-terminated string
480 .Fa str .
481 This is equivalent to calling
482 .Fn sbuf_cat
483 with a fresh
484 .Fa sbuf
485 or one which position has been reset to zero with
486 .Fn sbuf_clear
487 or
488 .Fn sbuf_setpos .
489 .Pp
490 The
491 .Fn sbuf_nl_terminate
492 function appends a trailing newline character, if the current line is non-empty
493 and not already terminated by a newline character.
494 .Pp
495 The
496 .Fn sbuf_printf
497 function formats its arguments according to the format string pointed
498 to by
499 .Fa fmt
500 and appends the resulting string to the
501 .Fa sbuf
502 at the current position.
503 .Pp
504 The
505 .Fn sbuf_vprintf
506 function behaves the same as
507 .Fn sbuf_printf
508 except that the arguments are obtained from the variable-length argument list
509 .Fa ap .
510 .Pp
511 The
512 .Fn sbuf_putc
513 function appends the character
514 .Fa c
515 to the
516 .Fa sbuf
517 at the current position.
518 .Pp
519 The
520 .Fn sbuf_trim
521 function removes trailing whitespace from the
522 .Fa sbuf .
523 .Pp
524 The
525 .Fn sbuf_error
526 function returns any error value that the
527 .Fa sbuf
528 may have accumulated, either from the drain function, or
529 .Er ENOMEM
530 if the
531 .Fa sbuf
532 overflowed.
533 This function is generally not needed and instead the error code from
534 .Fn sbuf_finish
535 is the preferred way to discover whether an sbuf had an error.
536 .Pp
537 The
538 .Fn sbuf_finish
539 function will call the attached drain function if one exists until all
540 the data in the
541 .Fa sbuf
542 is flushed.
543 If there is no attached drain,
544 .Fn sbuf_finish
545 NUL-terminates the
546 .Fa sbuf .
547 In either case it marks the
548 .Fa sbuf
549 as finished, which means that it may no longer be modified using
550 .Fn sbuf_setpos ,
551 .Fn sbuf_cat ,
552 .Fn sbuf_cpy ,
553 .Fn sbuf_printf
554 or
555 .Fn sbuf_putc ,
556 until
557 .Fn sbuf_clear
558 is used to reset the sbuf.
559 .Pp
560 The
561 .Fn sbuf_data
562 function returns the actual string;
563 .Fn sbuf_data
564 only works on a finished
565 .Fa sbuf .
566 The
567 .Fn sbuf_len
568 function returns the length of the string.
569 For an
570 .Fa sbuf
571 with an attached drain,
572 .Fn sbuf_len
573 returns the length of the un-drained data.
574 .Fn sbuf_done
575 returns non-zero if the
576 .Fa sbuf
577 is finished.
578 .Pp
579 The
580 .Fn sbuf_start_section
581 and
582 .Fn sbuf_end_section
583 functions may be used for automatic section alignment.
584 The arguments
585 .Fa pad
586 and
587 .Fa c
588 specify the padding size and a character used for padding.
589 The arguments
590 .Fa old_lenp
591 and
592 .Fa old_len
593 are to save and restore the current section length when nested sections
594 are used.
595 For the top level section
596 .Dv NULL
597 and \-1 can be specified for
598 .Fa old_lenp
599 and
600 .Fa old_len
601 respectively.
602 .Pp
603 The
604 .Fn sbuf_hexdump
605 function prints an array of bytes to the supplied sbuf, along with an ASCII
606 representation of the bytes if possible.
607 See the
608 .Xr hexdump 3
609 man page for more details on the interface.
610 .Pp
611 The
612 .Fn sbuf_printf_drain
613 function is a drain function that will call printf, or log to the console.
614 The argument
615 .Fa arg
616 must be either
617 .Dv NULL ,
618 or a valid pointer to a
619 .Vt size_t .
620 If
621 .Fa arg
622 is not
623 .Dv NULL ,
624 the total bytes drained will be added to the value pointed to by
625 .Fa arg .
626 .Pp
627 The
628 .Fn sbuf_putbuf
629 function printfs the sbuf to stdout if in userland, and to the console
630 and log if in the kernel.
631 The
632 .Fa sbuf
633 must be finished before calling
634 .Fn sbuf_putbuf .
635 It does not drain the buffer or update any pointers.
636 .Sh NOTES
637 If an operation caused an
638 .Fa sbuf
639 to overflow, most subsequent operations on it will fail until the
640 .Fa sbuf
641 is finished using
642 .Fn sbuf_finish
643 or reset using
644 .Fn sbuf_clear ,
645 or its position is reset to a value between 0 and one less than the
646 size of its storage buffer using
647 .Fn sbuf_setpos ,
648 or it is reinitialized to a sufficiently short string using
649 .Fn sbuf_cpy .
650 .Pp
651 Drains in user-space will not always function as indicated.
652 While the drain function will be called immediately on overflow from
653 the
654 .Fa sbuf_putc ,
655 .Fa sbuf_bcat ,
656 .Fa sbuf_cat
657 functions,
658 .Fa sbuf_printf
659 and
660 .Fa sbuf_vprintf
661 currently have no way to determine whether there will be an overflow
662 until after it occurs, and cannot do a partial expansion of the format
663 string.
664 Thus when using libsbuf the buffer may be extended to allow completion
665 of a single printf call, even though a drain is attached.
666 .Sh RETURN VALUES
667 The
668 .Fn sbuf_new
669 function returns
670 .Dv NULL
671 if it failed to allocate a storage buffer, and a pointer to the new
672 .Fa sbuf
673 otherwise.
674 .Pp
675 The
676 .Fn sbuf_setpos
677 function returns \-1 if
678 .Fa pos
679 was invalid, and zero otherwise.
680 .Pp
681 The
682 .Fn sbuf_bcat ,
683 .Fn sbuf_cat ,
684 .Fn sbuf_cpy ,
685 .Fn sbuf_printf ,
686 .Fn sbuf_putc ,
687 and
688 .Fn sbuf_trim
689 functions
690 all return \-1 if the buffer overflowed, and zero otherwise.
691 .Pp
692 The
693 .Fn sbuf_error
694 function returns a non-zero value if the buffer has an overflow or
695 drain error, and zero otherwise.
696 .Pp
697 The
698 .Fn sbuf_len
699 function returns \-1 if the buffer overflowed.
700 .Pp
701 The
702 .Fn sbuf_copyin
703 function
704 returns \-1 if copying string from userland failed, and number of bytes
705 copied otherwise.
706 .Pp
707 The
708 .Fn sbuf_end_section
709 function returns the section length or \-1 if the buffer has an error.
710 .Pp
711 The
712 .Fn sbuf_finish 9
713 function (the kernel version) returns
714 .Er ENOMEM
715 if the sbuf overflowed before being finished,
716 or returns the error code from the drain if one is attached.
717 .Pp
718 The
719 .Fn sbuf_finish 3
720 function (the userland version)
721 will return zero for success and \-1 and set errno on error.
722 .Sh EXAMPLES
723 .Bd -literal -compact
724 #include <sys/types.h>
725 #include <sys/sbuf.h>
726
727 struct sbuf *sb;
728
729 sb = sbuf_new_auto();
730 sbuf_cat(sb, "Customers found:\en");
731 TAILQ_FOREACH(foo, &foolist, list) {
732         sbuf_printf(sb, "   %4d %s\en", foo->index, foo->name);
733         sbuf_printf(sb, "      Address: %s\en", foo->address);
734         sbuf_printf(sb, "      Zip: %s\en", foo->zipcode);
735 }
736 if (sbuf_finish(sb) != 0) /* Check for any and all errors */
737         err(1, "Could not generate message");
738 transmit_msg(sbuf_data(sb), sbuf_len(sb));
739 sbuf_delete(sb);
740 .Ed
741 .Sh SEE ALSO
742 .Xr hexdump 3 ,
743 .Xr printf 3 ,
744 .Xr strcat 3 ,
745 .Xr strcpy 3 ,
746 .Xr copyin 9 ,
747 .Xr copyinstr 9 ,
748 .Xr printf 9
749 .Sh HISTORY
750 The
751 .Nm
752 family of functions first appeared in
753 .Fx 4.4 .
754 .Sh AUTHORS
755 .An -nosplit
756 The
757 .Nm
758 family of functions was designed by
759 .An Poul-Henning Kamp Aq Mt phk@FreeBSD.org
760 and implemented by
761 .An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org .
762 Additional improvements were suggested by
763 .An Justin T. Gibbs Aq Mt gibbs@FreeBSD.org .
764 Auto-extend support added by
765 .An Kelly Yancey Aq Mt kbyanc@FreeBSD.org .
766 Drain functionality added by
767 .An Matthew Fleming Aq Mt mdf@FreeBSD.org .
768 .Pp
769 This manual page was written by
770 .An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org .