]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - share/man/man9/sbuf.9
bhnd(9): Fix a few mandoc related issues
[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 26, 2020
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 the current position in the buffer.
374 It can only truncate the sbuf to the new position.
375 .Pp
376 The
377 .Fn sbuf_bcat
378 function appends the first
379 .Fa len
380 bytes from the buffer
381 .Fa buf
382 to the
383 .Fa sbuf .
384 .Pp
385 The
386 .Fn sbuf_bcopyin
387 function copies
388 .Fa len
389 bytes from the specified userland address into the
390 .Fa sbuf .
391 .Pp
392 The
393 .Fn sbuf_bcpy
394 function replaces the contents of the
395 .Fa sbuf
396 with the first
397 .Fa len
398 bytes from the buffer
399 .Fa buf .
400 .Pp
401 The
402 .Fn sbuf_cat
403 function appends the NUL-terminated string
404 .Fa str
405 to the
406 .Fa sbuf
407 at the current position.
408 .Pp
409 The
410 .Fn sbuf_set_drain
411 function sets a drain function
412 .Fa func
413 for the
414 .Fa sbuf ,
415 and records a pointer
416 .Fa arg
417 to be passed to the drain on callback.
418 The drain function cannot be changed while
419 .Fa sbuf_len
420 is non-zero.
421 .Pp
422 The registered drain function
423 .Vt sbuf_drain_func
424 will be called with the argument
425 .Fa arg
426 provided to
427 .Fn sbuf_set_drain ,
428 a pointer
429 .Fa data
430 to a byte string that is the contents of the sbuf, and the length
431 .Fa len
432 of the data.
433 If the drain function exists, it will be called when the sbuf internal
434 buffer is full, or on behalf of
435 .Fn sbuf_finish .
436 The drain function may drain some or all of the data, but must drain
437 at least 1 byte.
438 The return value from the drain function, if positive, indicates how
439 many bytes were drained.
440 If negative, the return value indicates the negative error code which
441 will be returned from this or a later call to
442 .Fn sbuf_finish .
443 If the returned drained length is 0, an error of
444 .Er EDEADLK
445 is set.
446 To do unbuffered draining, initialize the sbuf with a two-byte buffer.
447 The drain will be called for every byte added to the sbuf.
448 The
449 .Fn sbuf_bcopyin ,
450 .Fn sbuf_bcpy ,
451 .Fn sbuf_clear ,
452 .Fn sbuf_copyin ,
453 .Fn sbuf_cpy ,
454 .Fn sbuf_trim ,
455 .Fn sbuf_data ,
456 and
457 .Fn sbuf_len
458 functions cannot be used on an sbuf with a drain.
459 .Pp
460 The
461 .Fn sbuf_copyin
462 function copies a NUL-terminated string from the specified userland
463 address into the
464 .Fa sbuf .
465 If the
466 .Fa len
467 argument is non-zero, no more than
468 .Fa len
469 characters (not counting the terminating NUL) are copied; otherwise
470 the entire string, or as much of it as can fit in the
471 .Fa sbuf ,
472 is copied.
473 .Pp
474 The
475 .Fn sbuf_cpy
476 function replaces the contents of the
477 .Fa sbuf
478 with those of the NUL-terminated string
479 .Fa str .
480 This is equivalent to calling
481 .Fn sbuf_cat
482 with a fresh
483 .Fa sbuf
484 or one which position has been reset to zero with
485 .Fn sbuf_clear
486 or
487 .Fn sbuf_setpos .
488 .Pp
489 The
490 .Fn sbuf_nl_terminate
491 function appends a trailing newline character, if the current line is non-empty
492 and not already terminated by a newline character.
493 .Pp
494 The
495 .Fn sbuf_printf
496 function formats its arguments according to the format string pointed
497 to by
498 .Fa fmt
499 and appends the resulting string to the
500 .Fa sbuf
501 at the current position.
502 .Pp
503 The
504 .Fn sbuf_vprintf
505 function behaves the same as
506 .Fn sbuf_printf
507 except that the arguments are obtained from the variable-length argument list
508 .Fa ap .
509 .Pp
510 The
511 .Fn sbuf_putc
512 function appends the character
513 .Fa c
514 to the
515 .Fa sbuf
516 at the current position.
517 .Pp
518 The
519 .Fn sbuf_trim
520 function removes trailing whitespace from the
521 .Fa sbuf .
522 .Pp
523 The
524 .Fn sbuf_error
525 function returns any error value that the
526 .Fa sbuf
527 may have accumulated, either from the drain function, or
528 .Er ENOMEM
529 if the
530 .Fa sbuf
531 overflowed.
532 This function is generally not needed and instead the error code from
533 .Fn sbuf_finish
534 is the preferred way to discover whether an sbuf had an error.
535 .Pp
536 The
537 .Fn sbuf_finish
538 function will call the attached drain function if one exists until all
539 the data in the
540 .Fa sbuf
541 is flushed.
542 If there is no attached drain,
543 .Fn sbuf_finish
544 NUL-terminates the
545 .Fa sbuf .
546 In either case it marks the
547 .Fa sbuf
548 as finished, which means that it may no longer be modified using
549 .Fn sbuf_setpos ,
550 .Fn sbuf_cat ,
551 .Fn sbuf_cpy ,
552 .Fn sbuf_printf
553 or
554 .Fn sbuf_putc ,
555 until
556 .Fn sbuf_clear
557 is used to reset the sbuf.
558 .Pp
559 The
560 .Fn sbuf_data
561 function returns the actual string;
562 .Fn sbuf_data
563 only works on a finished
564 .Fa sbuf .
565 The
566 .Fn sbuf_len
567 function returns the length of the string.
568 For an
569 .Fa sbuf
570 with an attached drain,
571 .Fn sbuf_len
572 returns the length of the un-drained data.
573 .Fn sbuf_done
574 returns non-zero if the
575 .Fa sbuf
576 is finished.
577 .Pp
578 The
579 .Fn sbuf_start_section
580 and
581 .Fn sbuf_end_section
582 functions may be used for automatic section alignment.
583 The arguments
584 .Fa pad
585 and
586 .Fa c
587 specify the padding size and a character used for padding.
588 The arguments
589 .Fa old_lenp
590 and
591 .Fa old_len
592 are to save and restore the current section length when nested sections
593 are used.
594 For the top level section
595 .Dv NULL
596 and \-1 can be specified for
597 .Fa old_lenp
598 and
599 .Fa old_len
600 respectively.
601 .Pp
602 The
603 .Fn sbuf_hexdump
604 function prints an array of bytes to the supplied sbuf, along with an ASCII
605 representation of the bytes if possible.
606 See the
607 .Xr hexdump 3
608 man page for more details on the interface.
609 .Pp
610 The
611 .Fn sbuf_printf_drain
612 function is a drain function that will call printf, or log to the console.
613 The argument
614 .Fa arg
615 must be either
616 .Dv NULL ,
617 or a valid pointer to a
618 .Vt size_t .
619 If
620 .Fa arg
621 is not
622 .Dv NULL ,
623 the total bytes drained will be added to the value pointed to by
624 .Fa arg .
625 .Pp
626 The
627 .Fn sbuf_putbuf
628 function printfs the sbuf to stdout if in userland, and to the console
629 and log if in the kernel.
630 The
631 .Fa sbuf
632 must be finished before calling
633 .Fn sbuf_putbuf .
634 It does not drain the buffer or update any pointers.
635 .Sh NOTES
636 If an operation caused an
637 .Fa sbuf
638 to overflow, most subsequent operations on it will fail until the
639 .Fa sbuf
640 is finished using
641 .Fn sbuf_finish
642 or reset using
643 .Fn sbuf_clear ,
644 or its position is reset to a value between 0 and one less than the
645 size of its storage buffer using
646 .Fn sbuf_setpos ,
647 or it is reinitialized to a sufficiently short string using
648 .Fn sbuf_cpy .
649 .Pp
650 Drains in user-space will not always function as indicated.
651 While the drain function will be called immediately on overflow from
652 the
653 .Fa sbuf_putc ,
654 .Fa sbuf_bcat ,
655 .Fa sbuf_cat
656 functions,
657 .Fa sbuf_printf
658 and
659 .Fa sbuf_vprintf
660 currently have no way to determine whether there will be an overflow
661 until after it occurs, and cannot do a partial expansion of the format
662 string.
663 Thus when using libsbuf the buffer may be extended to allow completion
664 of a single printf call, even though a drain is attached.
665 .Sh RETURN VALUES
666 The
667 .Fn sbuf_new
668 function returns
669 .Dv NULL
670 if it failed to allocate a storage buffer, and a pointer to the new
671 .Fa sbuf
672 otherwise.
673 .Pp
674 The
675 .Fn sbuf_setpos
676 function returns \-1 if
677 .Fa pos
678 was invalid, and zero otherwise.
679 .Pp
680 The
681 .Fn sbuf_bcat ,
682 .Fn sbuf_cat ,
683 .Fn sbuf_cpy ,
684 .Fn sbuf_printf ,
685 .Fn sbuf_putc ,
686 and
687 .Fn sbuf_trim
688 functions
689 all return \-1 if the buffer overflowed, and zero otherwise.
690 .Pp
691 The
692 .Fn sbuf_error
693 function returns a non-zero value if the buffer has an overflow or
694 drain error, and zero otherwise.
695 .Pp
696 The
697 .Fn sbuf_len
698 function returns \-1 if the buffer overflowed.
699 .Pp
700 The
701 .Fn sbuf_copyin
702 function
703 returns \-1 if copying string from userland failed, and number of bytes
704 copied otherwise.
705 .Pp
706 The
707 .Fn sbuf_end_section
708 function returns the section length or \-1 if the buffer has an error.
709 .Pp
710 The
711 .Fn sbuf_finish 9
712 function (the kernel version) returns
713 .Er ENOMEM
714 if the sbuf overflowed before being finished,
715 or returns the error code from the drain if one is attached.
716 .Pp
717 The
718 .Fn sbuf_finish 3
719 function (the userland version)
720 will return zero for success and \-1 and set errno on error.
721 .Sh EXAMPLES
722 .Bd -literal -compact
723 #include <sys/types.h>
724 #include <sys/sbuf.h>
725
726 struct sbuf *sb;
727
728 sb = sbuf_new_auto();
729 sbuf_cat(sb, "Customers found:\en");
730 TAILQ_FOREACH(foo, &foolist, list) {
731         sbuf_printf(sb, "   %4d %s\en", foo->index, foo->name);
732         sbuf_printf(sb, "      Address: %s\en", foo->address);
733         sbuf_printf(sb, "      Zip: %s\en", foo->zipcode);
734 }
735 if (sbuf_finish(sb) != 0) /* Check for any and all errors */
736         err(1, "Could not generate message");
737 transmit_msg(sbuf_data(sb), sbuf_len(sb));
738 sbuf_delete(sb);
739 .Ed
740 .Sh SEE ALSO
741 .Xr hexdump 3 ,
742 .Xr printf 3 ,
743 .Xr strcat 3 ,
744 .Xr strcpy 3 ,
745 .Xr copyin 9 ,
746 .Xr copyinstr 9 ,
747 .Xr printf 9
748 .Sh HISTORY
749 The
750 .Nm
751 family of functions first appeared in
752 .Fx 4.4 .
753 .Sh AUTHORS
754 .An -nosplit
755 The
756 .Nm
757 family of functions was designed by
758 .An Poul-Henning Kamp Aq Mt phk@FreeBSD.org
759 and implemented by
760 .An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org .
761 Additional improvements were suggested by
762 .An Justin T. Gibbs Aq Mt gibbs@FreeBSD.org .
763 Auto-extend support added by
764 .An Kelly Yancey Aq Mt kbyanc@FreeBSD.org .
765 Drain functionality added by
766 .An Matthew Fleming Aq Mt mdf@FreeBSD.org .
767 .Pp
768 This manual page was written by
769 .An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org .