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