====== .ini files ======

''.ini'' files are used by Synchronet for //initialization// control, //configuration//, and //data-storage//.

===== Configuration =====

Synchronet's INI configuration files are typically stored in the ''[[dir:ctrl]]'' directory, with a ''.ini'' filename suffix/extension.

==== Primary Configuration Files ====

The primary configuration files managed by the [[util:SCFG]] utility are:
^ Filename    ^ Description ^
|''[[sbbs.ini]]'' |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/sbbs.ini|Synchronet Server Initialization File]] |
| ''main.ini'' | Primary system settings (e.g. BBS name, location, security settings) and command shells |
| ''msgs.ini'' | Message areas, message options, and message networking |
| ''file.ini'' | File areas (for uploads, download), text file areas, and file-related options |
| ''xtrn.ini'' | External program configurations which includes timed events, message editors, hot-key events and doors |
| ''chat.ini'' | Chat Features settings, specifically the Guru, Multi-node chat actions and channels, and external sysop pagers |
| ''node.ini'' | Located in the [[dir:node|node directories]], and configured via the SCFG [[config:nodes]] menu |

==== Secondary Configuration Files ====

^Filename Page             ^Default Contents^Description^
|''[[custom:text.ini]]''    |N/A | Customized ''text.dat'' strings (optional) |
|''text.//lang//.ini''      |varies | Alternate language ''text.ini'' files |
|''[[cgi_env.ini]]''        |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/cgi_env.ini|cgi_env.ini]]|[[server:Web]] Server CGI Settings|
|''[[formmail.ini]]''       |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/formmail.ini|formmail.ini]]|Configuration for ''[[dir:web]]/formmail.ssjs'', Synchronet's Server-side [[custom:JavaScript]] version of [[http://www.scriptarchive.com/formmail.html|FormMail]]|
|''[[ircbot.ini]]''         |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/ircbot.ini|ircbot.ini]]|Configuration for IRC robots, optionally works with the Synchronet [[service:IRCd]]|
|''[[ircd.ini]]''         |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/ircd.ini|ircd.ini]]|Configuration for IRC server. Replaces old ircd.conf on modern Synchronet [[service:IRCd]]|
|''[[listserver.ini]]''     |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/listserver.ini|listserver.ini]]|Configuration for the Synchronet ListServer module (''[[dir:exec]]/[[module:listserver]].js'')|
|''[[mailproc.ini]]''       |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/mailproc.ini|mailproc.ini]]|Configuration of External Mail Processors for the [[server:Mail]] Server (SMTP)|
|''[[mime_types.ini]]''     |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/mime_types.ini|mime_types.ini]]|MIME File Types registered in the [[server:Web]] Server|
|''[[modopts.ini]]''        |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/modopts.ini|modopts.ini]]|Configuration settings (options) for various [[custom:JavaScript]] modules, stock and/or 3rd party|
|''[[rss.ini]]''            |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/rss.ini|rss.ini]]|Configuration for Synchronet RSS Feed module (''[[dir:exec]]/rss.ssjs'')|
|''[[sbbsctrl.ini]]''       |N/A|Configuration for Synchronet Control Panel ([[monitor:SBBSCTRL]]) for Windows, exported from Windows Registry|
|''[[sbbsexec.ini]]''           |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/exec/sbbsexec.ini|sbbsexec.ini]]|Configuration for the Synchronet Virtual FOSSIL / UART Driver for Windows|
|''[[services.ini]]''       |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/services.ini|services.ini]]|Configuration for Synchronet [[service:|Services]]|
|''[[sexpots.ini]]''       |N/A|Configuration for Synchronet External POTS Support utility ([[util:SEXPOTS]])|
|''[[sexyz.ini]]''       |N/A|Configuration for Synchronet External X/Y/ZMODEM protocol driver ([[util:SEXYZ]])|
|''[[sockopts.ini]]''       |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/sockopts.ini|sockopts.ini]]|Configuration of TCP/IP socket options|
|''[[web_handler.ini]]''    |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/web_handler.ini|web_handler.ini]]|Configuration of special content (file type) handlers for the [[server:Web]] Server|
|''[[webicons.ini]]''       |[[https://gitlab.synchro.net/sbbs/sbbs/-/raw/master/ctrl/webicons.ini|webicons.ini]]|Configuration of icon files used to represent specific file types in the [[server:Web]] Server|

===== Database =====
INI files are also sometimes used for data storage (not related to configuration). This is popular with some JavaScript modules. Such files are typically stored in the ''[[dir:data]]'' or ''[[dir:xtrn]]'' directory hierarchies. When INI files are used for data storage purposes, they may or may not have a ''.ini'' file suffix/extension.

===== Filenaming =====

Synchronet supports a variety of configuration files of different formats. A growing majority of these configuration files are of the [[wp>INI file]] type. Synchronet's INI files are typically stored in the ''[[dir:ctrl]]'' directory, with a ''.ini'' filename suffix/extension.

Many of Synchronet's INI filenames support a flexible naming convention, for two reasons: so multi-host BBSes can share the same ''[[dir:ctrl]]'' directory but have a subset of unique INI files particular to each host, and so that your version of a file that //Synchronet distributes// can be kept separate from ours.

This flexible naming takes the normal base filename, for example, ''ctrl/services.ini'', and allows for the local host's name (host name or host.domain name), the platform description (e.g. "linux" or "win32"), or the word ''local'' to be inserted before the ''.ini'' filename suffix/extension.

The order of preference (using ''ctrl/services.ini'' as an example base filename) is:
  - ''ctrl/services.//host.domain//.ini''
  - ''ctrl/services.//host//.ini''
  - ''ctrl/services.//platform//.ini''
  - ''ctrl/services.local.ini''
  - ''ctrl/services.ini''

** NOTE: Only one file is actually used per host. **

==== The .local Variation ====

New in v3.22. The ''.local'' variation names //this installation// rather than a particular machine or operating system. Create it when the file you want to change is one that Synchronet distributes, so that your version stays separate from the one we ship.

How much this matters depends on where the file lives:

  * The ''[[dir:ctrl]]'' directory is populated when the BBS is **installed**, and an upgrade leaves it alone -- the Windows upgrade, for example, copies only ''text.dat'' into it. For a ''ctrl'' file the ''.local'' variation is therefore a convenience rather than a rescue: it keeps your settings in a file that is plainly yours and separable from ours.
  * The distributed program directories are a different matter. ''[[dir:exec]]'', ''[[dir:text]]'' and ''docs'' are refreshed by an upgrade, and ''[[dir:xtrn]]'' is refreshed whenever you accept the installer's //Upgrade Externals// option -- so an edit made directly to a file we ship in one of those can be replaced by a later version of it.
  * On a BBS run from a source-code checkout, updating means pulling the whole tree, and a file you have edited that we have also changed produces a merge conflict wherever it lives.

Because only one file is used, a ''.local'' file //replaces// the one it shadows rather than overriding parts of it. Start by copying the distributed file to the ''.local'' name, then edit the copy.

A per-host or per-platform variation still takes precedence over ''.local'' where one exists, so a multi-host BBS can go on using those for the settings that genuinely differ from machine to machine.

==== Which Files Support This ====

The flexible naming applies to the configuration files read by the servers and utilities -- among them [[sbbs.ini]], [[services.ini]], [[mailproc.ini]], [[mime_types.ini]], [[web_handler.ini]], ''web_alias.ini'', [[cgi_env.ini]], [[sockopts.ini]], ''jsexec.ini'', [[sexpots.ini]], [[sexyz.ini]] and [[sbbsexec.ini]] -- and to any [[custom:JavaScript]] module that resolves its configuration filename the same way.

It does //not// apply to the [[util:SCFG]]-managed primary configuration files (''main.ini'', ''msgs.ini'', ''file.ini'', ''xtrn.ini'', ''chat.ini''). Those are loaded by their exact filename and have no per-host, per-platform or ''.local'' variation: they describe the BBS itself, which is identical on every host. See [[howto:multihost]] for what a multi-host BBS should put where.

==== Case Sensitivity ====
The INI filenames are not case sensitive.

===== Syntax =====
Synchronet uses the XPDEV library for it's INI file parsing and creation. The XPDEV INI file syntax closely matches that of the common use in Windows applications. The basic syntax is:

<code ini>
; INI files are plain text files that may be edited with a common text editor.

; Lines beginning with a semicolon are considered "comments" and are ignored.

; Blank lines are ignored.

; Values are assigned to "keys" with the syntax "keyname=value" on a line by themselves.

SomeKey=100
SomeOtherKey=Hello, world.

; Keys are sometimes grouped together into "sections". 
; A "section" begins with the section name enclosed in square-brackets:
[section1]
SectionKey=true

; Additional sections may be included.
; Keys (even with the same name) will not collide with those in other sections:
[section2]
SectionKey=42
</code>

The Synchronet/XPDEV INI file format has some minor deviations from the Windows INI format:
==== Root Section ====

Some Synchronet INI files support the concept of a //root section//, that is, a virtual section that consists of a set of ''key=value'' pairs in the file before any ''[section]'' tags. The //root section// is typically used for global or default values for other sections in the INI file. In some INI files, the //root section// is the only supported section and discovery of any ''[section]'' tags will terminate the file.

Example:
<code ini>
; This is the top of the file

; This is the root section
RootKey=Value

[some section]
;This is a section named "some section" (not the "root section")
SomeSectionKey=Value
</code>
==== Named Sections ====

All sections in an INI file, except for the [[#Root Section]], have a name (or some times, multiple names). Section names are used by application programs and scripts to find the set of keys they are interested in. Section names are not case sensitive.

==== Section With Multiple Names ====

A single section may go by more than one section name by separating the names in the ''[section]'' tag with a pipe (''|'') symbol.

Example:
<code ini>
[Mail|Web]
; The keys in this section belong to both the "Mail" and "Web" sections 
</code>
Note: Since section names may not be reused in a single ''.ini'' file, a single section with more than one name will be the **only** representation of the named sections and any following section with one of the used names will be ignored.

==== String Literals ====

By using a colon character ('':'') rather than equals sign (''='') as a key/value separator, string value with embedded control characters and trailing white-space characters may be specified in ''.ini'' files.

=== Quotes ===
If the first non-white-space character following the colon key/value separate is a double-quote (''"'') character, then the string will be terminated at the last (right-most) double-quote character. This allows a string value to be specified with trailing white-space without risk that a text editor might remove it:
  mystring: "a string with trailing white-space "

=== Escape Sequences ===
Character values may be specified using C-style character literal escaping for control characters (e.g. ''\r'' for carriage-return, ''\n'' for line-feed, ''\x01'' for Ctrl-A, etc.) or CP437 characters (e.g. ''\xb3'' for a vertical bar).
==== Directives ====

INI file directives must be on a line by themselves and must begin with the ''!'' character.

=== EOF ===

A premature end-of-file may be defined by using the ''!eof'' directive. No lines after this directive will be parsed by the INI file parser.

Example:
  !eof

=== Include ===

Some INI files support the embedding of other files using the ''!include //filename//'' directive.

Example:
<code ini>
!include another.ini
</code>

In Synchronet v3.18c, the ability to include multiple files was added, e.g.

<code ini>
!include sub-dir/*.ini
</code>

===== Editing =====

When an INI file must be edited by hand, any good text file editor should work fine.

==== Line Lengths ====

Each line in an INI file cannot be more than 2045 characters in length.

==== Line Termination ====

Lines may be terminated with a single LF character (Unix style) or CR/LF pair (DOS/Windows style).

==== Value Lengths ====

The maximum length of a value that may be assigned to key (e.g. ''key=value'') is 1023 characters.

==== Value Termination ====

String values are terminated by a new-line sequence or the end of file.

Trailing white-space is normally removed from string values, unless the ''key:value'' (string literal) syntax is used instead of ''key=value''.

==== Comments ====

A line whose first non-white-space character is a semicolon (''%%;%%'') is a comment and is ignored in its entirety (as are blank lines).

A semicolon that appears //after a value// on a ''key=value'' line is **not** always the start of a comment. Whether the rest of the line is discarded depends on the //type// of value the key holds:

  * **String** values keep the semicolon and everything after it as //part of the value//. An inline "comment" after a string key therefore silently becomes part of the string. For example, the line ''%%endpoint = http://host:8080/ ; my note%%'' assigns the literal value ''%%http://host:8080/ ; my note%%'' (with trailing white-space trimmed), //not// the bare URL. Put comments for string keys on their own line //above// the key.
  * **Boolean**, **enumerated**, **numeric**, **byte**, and **date/time** values are single tokens, so a trailing semicolon (with or without preceding white-space) and any text after it are ignored. An inline comment following one of these values is safe -- e.g. ''%%Enabled = true   ; turned on%%'' evaluates as //true//.

When in doubt, put the comment on its own line.

=== JavaScript Modules ===

The same behavior applies when a [[custom:JavaScript]] module reads INI values. The ''File'' object's ''iniGetValue(section, key, default)'' method strips a trailing comment only when the //default// value selects a typed reader (e.g. a boolean or numeric default); a string default -- or no default -- returns the raw value with any inline comment still attached. ''iniGetObject(section)'' returns //every// value as a string, so it never strips inline comments. A script should not rely on inline comments being removed from the string-valued keys it reads.

==== Boolean Values ====
For keys that only support a simple //true// or //false// value, the following values will be evaluated as a //true// value:
  * ''true'' (case-insensitive)
  * ''yes'' (case-insensitive)
  * ''on'' (case-insensitive)
  * Any non-zero number

Any other value will be evaluated as a //false// value.

==== Byte Values ====

For keys that indicate a number of bytes (e.g. of memory, file, or disk), the value may be specified in kilobytes (e.g. ''500K''), megabytes (e.g. ''1.5M''), gigabytes (e.g. ''16G''), terabytes (''1T''), and exabytes (''0.5E'').

==== Enumerated Values ====

Some keys support values specified either by number (typically from ''0'' through n) or by a symbolic name for each supported value. These are referred to as enumerated values.

A numeric value higher than the highest supported enumerated value will be treated the same as the highest supported enumerated value.

When a word is provided as an enumerated key value, an initial partial word match is all that is required. So for example, a key value of "Debugging" would match the enum value of ''Debug'', and "Informational" would match the enum value of ''Info''. These string matches are also performed case-insensitively so "ERROR" and "error" are equivalents.

=== Log Levels ===

''LogLevel'' keys are one example of a key with enumerated values. The ''LogLevel'' value may be specified as a decimal number (from ''0'' to ''7'') or by specifying one of the following enumerated names:

^Value ^Name             ^ Description ^
|0     |''Emergency''    | Fatal condition |
|1     |''Alert''        | Very Serious condition |
|2     |''Critical''     | Serious condition |
|3     |''Error''        | Unexpected/erroneous condition |
|4     |''Warning''      | Suspicious condition |
|5     |''Notice''       | Infrequent event |
|6     |''Info''         | Common activity (AKA "Informational") |
|7     |''Debug''        | Extra detail sometimes helpful during issue analysis (AKA "Debugging") |

Log entries with a log level //higher// than the specified ''LogLevel'' value will not be logged/displayed.

The ''Debug'' (7) log level enables //all// possible log output.

==== Bit-field Values ====

Some key values may be specified as a series of numeric values separated by the ''|'' (ASCII 124) character. The numeric values may be specified with the literal decimal or hexadecimal value or, more commonly, using a representative name. The individual values are bit-wise OR'd together to produce the end result for the key value.

=== Options ===

''Options'' keys are one example of a key with a bit-field value. The value is usually made up of one or more option names separated by the ''|'' character. Which option names are supported depends on which //section// the ''Options'' key is located.

Common Options (e.g. from the [[sbbs.ini]] file) include:

  * ''NO_HOST_LOOKUP''
  * ''NO_RECYLCE''
  * ''NO_JAVASCRIPT''
  * ''GET_IDENT''
  * ''MUTE''

These could be specified in a ''.ini'' file like so:
<code ini>
Options = NO_HOST_LOOKUP | NO_RECYCLE | GET_IDENT
</code>

===== Source Code =====

Synchronet's INI file support comes from the XPDEV C library. The main source file is [[https://gitlab.synchro.net/sbbs/sbbs/-/blob/master/src/xpdev/ini_file.c]].

===== See Also =====

  * [[:config:index|Configuration]]
  * [[sbbs.ini]]
  * [[services.ini]] 
  * [[config:cfg_files|CFG Files]]
  * [[config:cnf_files|CNF Files]]
 

{{tag>configuration file_type ini}}