---
name: "bsddialog"
section: "3"
platform: "freebsd"
package: "base"
version: "16.0-CURRENT-20261027-61c70dc16a79"
release: "FreeBSD 16.0-CURRENT (2026-10-27)"
platforms: ["freebsd"]
url: "https://new.carta.tech/bsddialog/3"
---

# bsddialog(3)

TUI dialogs

## NAME

**bsddialog\_backtitle**, **bsddialog\_backtitle\_rf**, **bsddialog\_calendar**, **bsddialog\_clear**, **bsddialog\_color**, **bsddialog\_color\_attrs**, **bsddialog\_checklist**, **bsddialog\_datebox**, **bsddialog\_end**, **bsddialog\_form**, **bsddialog\_gauge**, **bsddialog\_geterror**, **bsddialog\_get\_theme**, **bsddialog\_hascolors**, **bsddialog\_infobox**, **bsddialog\_init**, **bsddialog\_init\_notheme**, **bsddialog\_initconf**, **bsddialog\_inmode**, **bsddialog\_menu**, **bsddialog\_mixedgauge**, **bsddialog\_mixedlist**, **bsddialog\_msgbox**, **bsddialog\_pause**, **bsddialog\_radiolist**, **bsddialog\_rangebox**, **bsddialog\_refresh**, **bsddialog\_set\_theme**, **bsddialog\_set\_default\_theme**, **bsddialog\_textbox**, **bsddialog\_timebox**, **bsddialog\_yesno** – TUI dialogs

## LIBRARY

library “libbsddialog”

## SYNOPSIS

**#include \<bsddialog.h\>**

*int*\

**bsddialog\_backtitle**(*struct bsddialog\_conf \*conf*, *const char \*backtitle*);

*int*\

**bsddialog\_backtitle\_rf**(*struct bsddialog\_conf \*conf*, *const char \*backtitle*);

*int*\

**bsddialog\_calendar**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*, *unsigned int \*year*, *unsigned int \*month*, *unsigned int \*day*);

*int*\

**bsddialog\_checklist**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*, *unsigned int menurows*, *unsigned int nitems*, *struct bsddialog\_menuitem \*items*, *int \*focusitem*);

*void*\

**bsddialog\_clear**(*unsigned int y*);

*int*\

**bsddialog\_datebox**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*, *unsigned int \*year*, *unsigned int \*month*, *unsigned int \*day*);

*int*\

**bsddialog\_end**(*void*);

*int*\

**bsddialog\_form**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*, *unsigned int formrows*, *unsigned int nitems*, *struct bsddialog\_formitem \*items*, *int \*focusitem*);

*int*\

**bsddialog\_gauge**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*, *unsigned int perc*, *int fd*, *const char \*sep*, *const char \*end*);

*const* *char* *\**\

**bsddialog\_geterror**(*void*);

*int*\

**bsddialog\_infobox**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*);

*int*\

**bsddialog\_init**(*void*);

*int*\

**bsddialog\_init\_notheme**(*void*);

*bool*\

**bsddialog\_inmode**(*void*);

*int*\

**bsddialog\_initconf**(*struct bsddialog\_conf \*conf*);

*int*\

**bsddialog\_menu**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*, *unsigned int menurows*, *unsigned int nitems*, *struct bsddialog\_menuitem \*items*, *int \*focusitem*);

*int*\

**bsddialog\_mixedgauge**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*, *unsigned int mainperc*, *unsigned int nminibars*, *char \*\*minilabels*, *int \*minipercs*);

*int*\

**bsddialog\_mixedlist**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*, *unsigned int menurows*, *unsigned int ngroups*, *struct bsddialog\_menugroup \*groups*, *int \*focuslist*, *int \*focusitem*);

*int*\

**bsddialog\_msgbox**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*);

*int*\

**bsddialog\_pause**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*, *unsigned int \*seconds*);

*int*\

**bsddialog\_radiolist**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*, *unsigned int menurows*, *unsigned int nitems*, *struct bsddialog\_menuitem \*items*, *int \*focusitem*);

*int*\

**bsddialog\_rangebox**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*, *int min*, *int max*, *int \*value*);

*void*\

**bsddialog\_refresh**(*void*);

*int*\

**bsddialog\_textbox**(*struct bsddialog\_conf \*conf*, *const char \*file*, *int rows*, *int cols*);

*int*\

**bsddialog\_timebox**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*, *unsigned int \*hh*, *unsigned int \*mm*, *unsigned int \*ss*);

*int*\

**bsddialog\_yesno**(*struct bsddialog\_conf \*conf*, *const char \*text*, *int rows*, *int cols*);

**#include \<bsddialog\_theme.h\>**

*int*\

**bsddialog\_color**(*enum bsddialog\_color foreground*, *enum bsddialog\_color background*, *unsigned int flags*);

*int*\

**bsddialog\_color\_attrs**(*int color*, *enum bsddialog\_color \*foreground*, *enum bsddialog\_color \*background*, *unsigned int \*flags*);

*int*\

**bsddialog\_get\_theme**(*struct bsddialog\_theme \*theme*);

*bool*\

**bsddialog\_hascolors**(*void*);

*int*\

**bsddialog\_set\_default\_theme**(*enum bsddialog\_default\_theme theme*);

*int*\

**bsddialog\_set\_theme**(*struct bsddialog\_theme \*theme*);

## DESCRIPTION

The **bsddialog** library provides an API to build Text User Interface dialogs and widgets.

**bsddialog\_init**() initializes the library, the only functions that can be called before is **bsddialog\_initconf**() described later. After the initialization the input and output should be handled via the library API.

**bsddialog\_init\_notheme**() is equivalent to **bsddialog\_init**() except it does not set the default graphical theme; see Theme subsection to set a theme explicitly.

**bsddialog\_end**() restores the screen like before **bsddialog\_init**(). After the call is not possible to use the library functions.

**bsddialog\_inmode**() returns true after **bsddialog\_init**() or **bsddialog\_init\_notheme**() and before **bsddialog\_end**(), false otherwise.

**bsddialog\_backtitle\_rf**() prints *backtitle* on the top of the screen. The function handles *conf.ascii\_lines* and *conf.no\_lines* described later.

**bsddialog\_backtitle**() is like **bsddialog\_backtitle\_rf**() but it does not update the screen, using if a dialog is built later.

**bsddialog\_error**() returns a string to describe the last error. The function should be called after a BSDDIALOG\_ERROR returned value.

**bsddialog\_clear**() clears the screen from *y*.

**bsddialog\_refresh**() useful to refresh the screen after a terminal mode change, see [terminfo(5)](/terminfo/5.md).

### Dialogs

The dialogs have common arguments. *text* is a string printed inside the dialog. Each *char\** parameter can be a multibyte character string depending on current locale, see [setlocale(3)](/setlocale/3.md). *rows* and *cols* are height and width, their value can be a fixed size, BSDDIALOG\_AUTOSIZE or BSDDIALOG\_FULLSCREEN. *conf* is a struct to customize the current dialog, it does not set global properties to the library.

```
struct bsddialog_conf {
	bool ascii_lines;
	unsigned int auto_minheight;
	unsigned int auto_minwidth;
	unsigned int auto_topmargin;
	unsigned int auto_downmargin;
	const char *bottomtitle;
	bool clear;
	int *get_height;
	int *get_width;
	bool no_lines;
	bool shadow;
	unsigned int sleep;
	const char *title;
	int y;
	int x;
	struct {
		bool enable_esc;
		const char *f1_file;
		const char *f1_message;
	} key;
	struct {
		unsigned int cols_per_row;
		bool escape;
		unsigned int tablen;
	} text;
	struct {
		bool align_left;
		bool no_desc;
		bool no_name;
		bool shortcut_buttons;
	} menu;
	struct {
		char securech;
		char *securembch;
		bool value_wchar;
	} form;
	struct {
		const char *format;
	} date;
	struct {
		bool always_active;
		const char *left1_label;
		const char *left2_label;
		const char *left3_label;
		bool without_ok;
		const char *ok_label;
		bool with_extra;
		const char *extra_label;
		bool without_cancel;
		const char *cancel_label;
		bool default_cancel;
		bool with_help;
		const char *help_label;
		const char *right1_label;
		const char *right2_label;
		const char *right3_label;
		const char *default_label;
	} button;
};
```

| |
| --- |
| *conf.ascii\_lines* |
| *conf.auto\_minheight* |
| *conf.auto\_minwidth* |
| *conf.auto\_topmargin* |
| *conf.auto\_downmargin* |
| *conf.bottomtitle* |
| *conf.clear* |
| *conf.get\_height* |
| *conf.get\_width* |
| *conf.no\_lines* |
| *conf.shadow* |
| *conf.sleep* |
| *conf.title* |
| *conf.y* |
| *conf.x* |

| |
| --- |
| *conf.key.enable\_esc* |
| *conf.key.f1\_file* |
| *conf.key.f1\_message* |

| |
| --- |
| *conf.text.cols\_per\_row* |
| *conf.text.escape* |
| “\\Z0” |
| “\\Z1” |
| “\\Z2” |
| “\\Z3” |
| “\\Z4” |
| “\\Z5” |
| “\\Z6” |
| “\\Z7” |
| “\\Zb” |
| “\\ZB” |
| “\\Zd” |
| “\\ZD” |
| “\\Zk” |
| “\\ZK” |
| “\\Zr” |
| “\\ZR” |
| “\\Zs” |
| “\\ZS” |
| “\\Zu” |
| “\\ZU” |
| “\\Zn” |
| *conf.text.tablen* |

| |
| --- |
| *conf.button.always\_active* |
| *conf.button.left1\_label* |
| *conf.button.left2\_label* |
| *conf.button.left3\_label* |
| *conf.button.without\_ok* |
| *conf.button.ok\_label* |
| *conf.button.with\_extra* |
| *conf.button.extra\_label* |
| *conf.button.without\_cancel* |
| *conf.button.cancel\_label* |
| *conf.button.default\_cancel* |
| *conf.button.with\_help* |
| *conf.button.help\_label* |
| *conf.button.right1\_label* |
| *conf.button.right2\_label* |
| *conf.button.right3\_label* |
| *conf.button.default\_label* |

**bsddialog\_initconf**() initializes *conf* disabling each property, except *conf.shadow* to true, *conf.y* and *conf.x* to BSDDIALOG\_CENTER, *conf.text.cols\_per\_row* to 10.

**bsddialog\_calendar**() builds a dialog to select a date. *year*, *month*, and *day* are default values on startup, selected date at exit.

**bsddialog\_checklist**() builds dialogs to select some item from a list via the SPACE key, can be customized by *conf.menu.\**. See **bsddialog\_menu**().

**bsddialog\_datebox**() builds a dialog to select a date. *year*, *month*, and *day* are default values on startup, selected date at exit. The function can be customized by:

| |
| --- |
| *conf.date.format* |

**bsddialog\_form**() builds a dialog to display an array of *items* of *nitems* elements to get input strings. *formrows* is the graphical height for the items inside the dialog, 0 for autosizing. If not NULL *focusitem* is the default item index on startup and the last focused item at exit, a negative value if no item is focused. An item is defined like:

```
struct bsddialog_formitem {
	const char *label;
	unsigned int ylabel;
	unsigned int xlabel;
	const char *init;
	unsigned int yfield;
	unsigned int xfield;
	unsigned int fieldlen;
	unsigned int maxvaluelen;
	char *value;
	unsigned int flags;
	const char *bottomdesc;
};
```

*label* is a string to describe the request at the position *ylabel* and *xlabel*. The field for the input is at the position *yfield* and *xfield*, *fieldlen* is its graphical width, while *maxvalelen* is the maximum number of characters of the input string. *init* is the default field value. If no error occurs *value* is the allocated memory with the current field string at exit, its size depends on the current locale. *flags* is an OR value to set the field: BSDDIALOG\_FIELDHIDDEN, BSDDIALOG\_FIELDREADONLY, BSDDIALOG\_FIELDNOCOLOR, BSDDIALOG\_FIELDCURSOREND, BSDDIALOG\_FIELDEXTEND, BSDDIALOG\_FIELDSINGLEBYTE. *bottomdesc* is printed at bottom screen if the item is focused.

**bsddialog\_form**() can be customized by:

| |
| --- |
| *conf.form.securech* |
| *conf.form.securembch* |
| *conf.form.value\_wchar* |

**bsddialog\_gauge**() builds a dialog with a bar to show *perc*. If the file descriptor *fd* is greater or equal to 0 the dialog waits to read *sep* from it, then the first string replaces *perc* and the following strings replace *text* until the next *sep*, the loop ends reading *end*.

**bsddialog\_infobox**() builds a dialog without buttons and returns instantly.

**bsddialog\_menu**() builds a dialog to select an item from a list via SPACE and ENTER. An item is defined like:

```
struct bsddialog_menuitem {
	const char *prefix;
	bool on;
	unsigned int depth;
	const char *name;
	const char *desc;
	const char *bottomdesc;
};
```

*prefix*, *name* and *desc* are printed at the item row. *bottomdesc* is printed at bottom screen if the item is focused. *depth* is a margin between *prefix* and *name*. At exit *on* is set to true if the item is selected, false otherwise. *items* is an array of items of *nitem* elements. *menurows* is the graphical height of the list inside the dialog, if *cols* is BSDDIALOG\_AUTOSIZE *menurows* specifies a maximum value. if not NULL *focusitem* is the default item index on startup and the last focused item at exit, a negative value if no item is focused.

**bsddialog\_checklist**(), **bsddialog\_menu**(), **bsddialog\_mixedlist**() and **bsddialog\_radiolist**() can be customized by:

| |
| --- |
| *conf.menu.align\_left* |
| *conf.menu.no\_desc* |
| *conf.menu.no\_name* |
| *conf.menu.shortcut\_buttons* |

**bsddialog\_mixedgauge**() builds a dialog with a main bar with the *mainperc* percentage and *nminibars* each one with a *minilabel* and a *miniperc*. *miniperc* can be: a positive value to print a bar with a percentace, a negative constant BSDDIALOG\_MG\_SUCCEEDED, BSDDIALOG\_MG\_FAILED, BSDDIALOG\_MG\_PASSED, BSDDIALOG\_MG\_COMPLETED, BSDDIALOG\_MG\_CHECKED, BSDDIALOG\_MG\_DONE, BSDDIALOG\_MG\_SKIPPED, BSDDIALOG\_MG\_INPROGRESS, BSDDIALOG\_MG\_BLANK to hide *miniperc*, BSDDIALOG\_MG\_NA, BSDDIALOG\_MG\_PENDING to print a descriptive string, otherwise “UNKNOWN” is printed.

**bsddialog\_mixedlist**() builds a dialog with collections of checklists, radiolists and separators. A collection is a set defined like:

```
enum bsddialog_menutype {
	BSDDIALOG_CHECKLIST,
	BSDDIALOG_RADIOLIST,
	BSDDIALOG_SEPARATOR,
};
struct bsddialog_menugroup {
	enum bsddialog_menutype type;
	unsigned int nitems;
	struct bsddialog_menuitem *items;
	unsigned int min_on; /* unused for now */
};
```

*groups* is an array of sets of *ngroups* elements. *menurows* is the graphical height size for the list. If not NULL, *focuslist* and *focusitem* specify the default item on startup and the last focused item at exit, could be a negative value if no item is focused. The dialog can be customized by *conf.menu.\**, see **bsddialog\_menu**().

**bsddialog\_msgbox**() builds a dialog with OK button.

**bsddialog\_pause**() builds a dialog waiting until the timeout in *seconds* expires or a button is pressed. At exit *seconds* is set like remaining time.

**bsddialog\_radiolist**() builds dialogs to select at most an item from a list via the SPACE key, can be customized by *conf.menu.\**. See **bsddialog\_menu**().

**bsddialog\_rangebox**() to select a value between *min* and *max*. *value* is the default value on startup and the selected value at exit. The current value is printed inside a bar.

**bsddialog\_textbox**() opens and prints *file*. TAB key changes button. Extra keys 0, h, l, k, j are available to navigate the text. “OK” button is renamed “EXIT”.

**bsddialog\_timebox**() builds a dialog to choose a time. *hh*, *mm*, and *ss* are default values on startup, selected time at exit.

**bsddialog\_yesno**() provides a dialog for a “Yes-No Question”, the labels on buttons are “Yes” and “&No”.

### Keys

- Ctrl-l

  Redraw the dialog.

- F1

  Refer to *conf.key.f1\_file* and *conf.key.f1\_message*.

- SPACE

  Select menu item.

- UP DOWN LEFT RIGHT - + HOME END PAGEUP PAGEDOWN Ctrl-p Ctrl-n TAB

  Navigate elements and set value, depending on the dialog.

### Theme

The graphical properties are global to the library. They are represented by *struct*, *bsddialog\_theme* and can be customized at runtime via the ⟨bsddialog\_theme.h⟩ API.

```
struct bsddialog_theme {
	struct {
		int color;
	} screen;
	struct {
		int color;
		unsigned int y;
		unsigned int x;
	} shadow;
	struct {
		int  color;
		bool delimtitle;
		int  titlecolor;
		int  lineraisecolor;
		int  linelowercolor;
		int  bottomtitlecolor;
		int  arrowcolor;
	} dialog;
	struct {
		int f_prefixcolor;
		int prefixcolor;
		int f_selectorcolor;
		int selectorcolor;
		int f_namecolor;
		int namecolor;
		int f_desccolor;
		int desccolor;
		int f_shortcutcolor;
		int shortcutcolor;
		int bottomdesccolor;
		int sepnamecolor;
		int sepdesccolor;
	} menu;
	struct {
		int f_fieldcolor;
		int fieldcolor;
		int readonlycolor;
		int bottomdesccolor;
	} form;
	struct {
		int f_color;
		int color;
	} bar;
	struct {
		unsigned int minmargin;
		unsigned int maxmargin;
		char leftdelim;
		char rightdelim;
		int f_delimcolor;
		int delimcolor;
		int f_color;
		int color;
		int f_shortcutcolor;
		int shortcutcolor;
	} button;
};
```

A member with the “f\_” refers to focus when an element can be in selected or not selected state.

**bsddialog\_color**() generates and returns a color to set a *struct*, *bsddialog\_theme* color member. An *enum*, *bsddialog\_color* can be: BSDDIALOG\_BLACK, BSDDIALOG\_RED, BSDDIALOG\_GREEN, BSDDIALOG\_YELLOW, BSDDIALOG\_BLUE, BSDDIALOG\_MAGENTA, BSDDIALOG\_CYAN, BSDDIALOG\_WHITE. *flags* is an OR value: BSDDIALOG\_BLINK, BSDDIALOG\_BOLD, BSDDIALOG\_HALFBRIGHT, BSDDIALOG\_HIGHLIGHT, BSDDIALOG\_REVERSE, BSDDIALOG\_UNDERLINE.

**bsddialog\_color\_attrs**() sets, if not NULL, *foreground*, *background*, *flags*, like the properties of *color*, see **bsddialog\_color**().

**bsddialog\_get\_theme**() sets *theme* like the current runtime theme.

**bsddialog\_hascolors**() returns true if the terminal provides colors, false otherwise.

**bsddialog\_set\_theme**() sets *theme* like current runtime theme. Changes take effect only for dialogs built after the call.

**bsddialog\_set\_default\_theme**() sets a library default theme like current theme, possible values: BSDDIALOG\_THEME\_BLACKWHITE, BSDDIALOG\_THEME\_FLAT, BSDDIALOG\_THEME\_3D. Changes take effect only for dialogs built after the call.

## RETURN VALUES

The functions return the value BSDDIALOG\_ERROR if unsuccessful; otherwise, depending on the pressed button, the following values can be returned: BSDDIALOG\_OK, BSDDIALOG\_CANCEL, BSDDIALOG\_HELP, BSDDIALOG\_EXTRA, BSDDIALOG\_LEFT1, BSDDIALOG\_LEFT2, BSDDIALOG\_LEFT3, BSDDIALOG\_RIGHT1, BSDDIALOG\_RIGHT2, BSDDIALOG\_RIGHT3. BSDDIALOG\_YES and BSDDIALOG\_NO are aliases for BSDDIALOG\_OK and BSDDIALOG\_CANCEL, respectively.

The functions return BSDDIALOG\_ESC if *conf.key.enable\_esc* is enabled and the ESC key is pressed.

**bsddialog\_pause**() returns BSDDIALOG\_TIMEOUT if the timeout expires.

## EXAMPLES

“Yes-No Question” Example:

```
int output;
struct bsddialog_conf conf;
if (bsddialog_init() == BSDDIALOG_ERROR)
	return (1);
bsddialog_initconf(&conf);
conf.title = "yesno";
output = bsddialog_yesno(&conf, "Example", 7, 25);
bsddialog_end();
switch (output) {
case BSDDIALOG_YES:
	printf("Yes\n");
	break;
case BSDDIALOG_NO
	printf("No\n");
	break;
case BSDDIALOG_ERROR:
	printf("Error: %s\n", bsddialog_geterror());
	break;
}
```

Theme Example:

```
struct bsddialog_conf conf;
struct bsddialog_theme theme;
bsddialog_init();
bsddialog_initconf(&conf);
bsddialog_msgbox(&conf, "Default theme", 7, 25);
bsddialog_get_theme(&theme);
theme.screen.color = bsddialog_color(BSDDIALOG_RED, BSDDIALOG_GREEN,
    BSDDIALOG_BOLD);
bsddialog_set_theme(&theme);
bsddialog_backtitle(&conf, "Red foreground and Green background");
bsddialog_msgbox(&conf, "Change screen color", 7, 25);
bsddialog_set_default_theme(BSDDIALOG_THEME_BLACKWHITE);
bsddialog_msgbox(&conf, "Black and White theme", 7, 25);
bsddialog_end();
```

Mixedlist Example:

```
unsigned int i, j;
struct bsddialog_conf conf;
struct bsddialog_menuitem item;
struct bsddialog_menuitem check[2] = {
    { "1", true,  0, "Name 1", "Desc 1", "Check Bottom Desc 1" },
    { "2", false, 0, "Name 2", "Desc 2", "Check Bottom Desc 2" }
};
struct bsddialog_menuitem sep[1] = {
    { "3", true, 0, "Radiolist", "(desc)", "" }
};
struct bsddialog_menuitem radio[2] = {
    { "4", true,  0, "Name 1", "Desc 1", "Radio Bottom Desc 1" },
    { "5", false, 0, "Name 2", "Desc 2", "Radio Bottom Desc 2" }
};
struct bsddialog_menugroup group[3] = {
    { BSDDIALOG_CHECKLIST, 2, check },
    { BSDDIALOG_SEPARATOR, 1, sep   },
    { BSDDIALOG_RADIOLIST, 2, radio }
};
bsddialog_init();
bsddialog_initconf(&conf);
bsddialog_mixedlist(&conf, "Example", 20, 30, 11, 3, group, NULL,
    NULL);
bsddialog_end();
for (i = 0; i < 3; i++) {
	for (j = 0; j < group[i].nitems; j++) {
		item = group[i].items[j];
		switch (item.type) {
		case BSDDIALOG_SEPARATOR:
			printf("---- %s ----\n", item.name);
			break;
		case BSDDIALOG_RADIOLIST:
			printf(" (%c) %s\n",
			    item.on ? '*' : ' ', item.name);
			break;
		case BSDDIALOG_CHECKLIST:
			printf(" [%c] %s\n",
			    item.on ? 'X' : ' ', item.name);
			break;
		}
	}
}
```

## SEE ALSO

[bsddialog(1)](/bsddialog/1.md), [curses(3)](/curses/3.md)

## HISTORY

The **bsddialog** library first appeared in FreeBSD 14.0.

## AUTHORS

**bsddialog** was written by Alfonso Sabato Siciliano ⟨*asiciliano@FreeBSD.org*⟩.
