====== External Programs ======

To configure external programs or scripts that are to be executed from the Synchronet [[server:Terminal]] Server, use the [[util:SCFG]]->External Programs menu.

  ╔══════════════════════════╗
  ║     External Programs    ║
  ╠══════════════════════════╣
  ║ │Fixed Events            ║
  ║ │Timed Events            ║
  ║ │Native Program List     ║
  ║ │Message Editors         ║
  ║ │Global Hot Key Events   ║
  ║ │Online Programs (Doors) ║
  ╚══════════════════════════╝

From this menu you can configure the various ways Synchronet runs external programs and scripts: scheduled and lifecycle events, native-vs-DOS dispatch hints, the user-facing message-editor list, global hot-key events, and the classic //doors// (online programs) section users see in the BBS. All of these run under the [[server:terminal|Terminal Server]] — events run on its event thread; the rest run in the context of an online user node.

===== Fixed Events =====

Fixed Events are sysop-configurable command lines run by the BBS at well-known points (user lifecycle events and scheduled maintenance).

  ╔═══════════════════════════════════════════════════╗
  ║                    Fixed Events                   ║
  ╠═══════════════════════════════════════════════════╣
  ║ │New User                                         ║
  ║ │Logon                                            ║
  ║ │Logout                                           ║
  ║ │Daily       ?logonlist -m                        ║
  ║ │Weekly                                           ║
  ║ │Monthly     %!trashman%. %z*.can %kspamblock.cfg ║
  ╚═══════════════════════════════════════════════════╝

^ Event ^ When it runs ^ Typical use ^
| New User | Immediately after a new user account is created | New-user welcome mail, audit logging |
| Logon    | Each terminal logon (after the [[config:system#loadable_modules|Logon module]]) | Per-logon notifications, statistics updates |
| Logout   | Each terminal logout | Cleanup, per-session reporting |
| Daily    | Once per day, after the first caller after midnight logs off | Daily maintenance (e.g. ''logonlist -m'', ''cleanup.js'') |
| Weekly   | Once per week | Weekly stats / digest scripts |
| Monthly  | Once per month | Monthly maintenance (e.g. trashman / spam-list refresh) |

Selecting a Fixed Event opens a sub-menu with the event's command-line options:

^ Option Name ^ Description ^
| Enabled              | Master switch for this event. Set to ''No'' to suppress execution without losing the configured command line. |
| Native Executable    | ''Yes'' if the command is a native (non-DOS) executable; ''No'' for DOS programs needing a DOS emulator on *nix. |
| Use Shell or New Context | If ''Yes'', the command is run via a shell rather than executed directly. |
| Command Line         | The [[config:cmdline|command line]] to execute. Supports the standard command-line specifiers. |

===== Timed Events =====

 This is a list of the configured timed external events.

  ╔═════════════════════════════════════════════════════════════╗
  ║                      Timed Events (15)                      ║
  ╠═════════════════════════════════════════════════════════════╣
  ║ │FIDOIN            <DISABLED>                               ║
  ║ │FIDOOUT           <DISABLED>                               ║
  ║ │NEWSLINK          <DISABLED>                               ║
  ║ │CHKSPACE          ?chkspace.js %g %j                       ║
  ║ │SMB2SBL           ?sbbslist import                         ║
  ║ │SBL2SMB           ?sbbslist export                         ║
  ║ │SBLUPDAT          ?sbbslist update -preview                ║
  ║ │SBLMAINT          ?sbbslist maint                          ║
  ║ │MSGMAINT          %!smbutil%. mp1000 *.shd                 ║
  ║ │DELFILES          ?delfiles                                ║
  ║ │GETIMLST          ?wget ftp://ftp.synchro.net/sbbsimsg.lst ║
  ║ │LISTSERV          <DISABLED>                               ║
  ║ │DYNDNS            <DISABLED>                               ║
  ║ │AVAT-IN           ?avatars import                          ║
  ║ │AVAT-OUT          ?avatars export                          ║
  ║ │                                                           ║
  ╚═════════════════════════════════════════════════════════════╝

==== Timed Event ====

Configuration menu for a single timed event. A timed event is an external program or module that performs some automated function (e.g. mail-base maintenance, file-base updates, network polling). Configure how and when it executes:

  ╔════════════════════════════════════════════════════════════════════╗
  ║                         FIDOIN Timed Event                         ║
  ╠════════════════════════════════════════════════════════════════════╣
  ║ │Internal Code              FIDOIN                                 ║
  ║ │Start-up Directory                                                ║
  ║ │Command Line               %!sbbsecho%. -ce                       ║
  ║ │Enabled                    No                                     ║
  ║ │Execution Node             1                                      ║
  ║ │Execution Months           Any                                    ║
  ║ │Execution Days of Month    Any                                    ║
  ║ │Execution Days of Week     None                                   ║
  ║ │Execution Time             00:00                                  ║
  ║ │Requires Exclusive Exec    No                                     ║
  ║ │Force Users Off-line       No                                     ║
  ║ │Native Executable          Yes                                    ║
  ║ │Use Shell or New Context   No                                     ║
  ║ │Background Execution       No                                     ║
  ║ │Always Run After (re)Init  No                                     ║
  ║ │Error Log Level            Error                                  ║
  ╚════════════════════════════════════════════════════════════════════╝

^ Option Name              ^ Description ^
| Internal Code             | Up to 16 characters; uniquely identifies this event. Used in log files and as the base for any associated semaphore files. |
| Start-up Directory        | Directory the program is launched in (its working directory). Leave blank to use Synchronet's default. |
| Command Line              | The [[config:cmdline|command line]] to execute. Supports all standard specifiers (e.g. ''%!'' = exec dir, ''%j'' = data dir, ''%k'' = ctrl dir). |
| Enabled                   | Master switch. ''No'' suppresses execution without losing the configured schedule. |
| Execution Node            | Which node should execute the event (events are usually scheduled to run on one specific node, e.g. node 1). |
| Execution Months          | Restricts execution to specific months (default: Any). |
| Execution Days of Month   | Restricts execution to specific days of the month (default: Any). |
| Execution Days of Week    | Restricts execution to specific days of the week. //None// disables weekly scheduling (use Time-of-day or Frequency instead). |
| Execution Time            | Time of day (24-hour) when the event runs. //Or// **Execution Frequency** appears here when set — events can run every N minutes/hours instead of at a fixed time. |
| Requires Exclusive Exec   | If ''Yes'', no other event will run concurrently. Use for events that must run in isolation (e.g. message-base maintenance). |
| Force Users Off-line      | If ''Yes'', users are forcibly disconnected before the event runs. Use for invasive operations (e.g. full message-base packing). |
| Native Executable         | ''Yes'' for native (non-DOS) executables; ''No'' for DOS programs (require a DOS emulator on *nix). |
| Use Shell or New Context  | If ''Yes'', launch via a shell rather than direct exec. |
| Background Execution      | If ''Yes'', the event runs in the background and Synchronet does not wait for it to complete. |
| Always Run After (re)Init | If ''Yes'', the event runs once whenever the BBS (re)starts, in addition to its normal schedule. |
| Error Log Level           | Minimum severity at which event execution errors are logged (Debug / Informational / Warning / Error / Critical / Alert / Emergency). |

===== Native Program List =====

A simple list of executable basenames that Synchronet should treat as **native** (non-DOS) programs even when they are not individually flagged as ''Native Executable'' in their per-program configuration. Any external program whose first word matches a name in this list is executed natively without involving a DOS emulator.

  ╔════════════════════════════╗
  ║     Native Program List    ║
  ╠════════════════════════════╣
  ║ │cmd.exe                   ║
  ║ │sh                        ║
  ║ │csh                       ║
  ║ │bash                      ║
  ║ │node                      ║
  ║ │smbutil                   ║
  ║ │zip                       ║
  ║ │unzip                     ║
  ║ │pkzip25                   ║
  ║ │mp3info                   ║
  ║ │                          ║
  ╚════════════════════════════╝

  * Use ''Ins'' / ''Del'' to add or remove names.
  * Names are matched against the first whitespace-delimited token of an external program's command line (after [[config:cmdline|command-line specifier]] expansion).
  * On modern installs where DOS programs are rare, this list is rarely needed — programs that need it are typically already flagged ''Native Executable'' in their own per-program config.


===== Message Editors =====
This is a list of the configured external message editors.

  ╔═══════════════════════════════════════════╗
  ║              Message Editors              ║
  ╠═══════════════════════════════════════════╣
  ║ │FSEDITOR          ?fseditor %f           ║
  ║ │SLYEICE           ?slyedit %f ICE        ║
  ║ │SLYEDCT           ?slyedit %f DCT        ║
  ║ │                                         ║
  ╚═══════════════════════════════════════════╝

==== Message Editor ====
Configuration menu for one external message editor. Popular editors include [[module:fseditor|FSEditor]], [[module:slyedit|SlyEdit]], SyncEdit, WWIVedit, FEdit, GEdit, IceEdit.

  ╔════════════════════════════════════════════════════════════════════╗
  ║                       Deuce's FSEditor Editor                      ║
  ╠════════════════════════════════════════════════════════════════════╣
  ║ │Name                            Deuce's FSEditor                  ║
  ║ │Internal Code                   FSEDITOR                          ║
  ║ │Command Line                    ?fseditor %f                      ║
  ║ │Access Requirements             ANSI                              ║
  ║ │Native Executable               Yes                               ║
  ║ │I/O Method                      Socket                            ║
  ║ │Use Shell or New Context        No                                ║
  ║ │Record Terminal Width           Yes                               ║
  ║ │Word-wrap Quoted Text           Yes, for terminal width           ║
  ║ │Retain Ctrl-A Codes in Quotes   No                                ║
  ║ │Automatically Quoted Text       None                              ║
  ║ │Editor Information Files        WWIV EDITOR.INF/RESULT.ED         ║
  ║ │Handle Soft CRs                 N/A                               ║
  ║ │Strip FidoNet Kludges           No                                ║
  ║ │Support UTF-8 Encoding          Yes                               ║
  ║ │BBS Drop File Type              None                              ║
  ╚════════════════════════════════════════════════════════════════════╝

^ Option Name                  ^ Description ^
| Name                          | Display name shown to users when selecting an editor. |
| Internal Code                 | Up to 16 characters; uniquely identifies this editor. Stored as the user's editor preference. |
| Command Line                  | The [[config:cmdline|command line]] to invoke the editor. ''%f'' expands to the message-text file the editor should edit. |
| Access Requirements           | An [[access:requirements|ARS]] expression — only users matching the requirements may use this editor. Common: ''ANSI'' for full-screen editors. |
| Native Executable             | ''Yes'' for native binaries; ''No'' for DOS programs. |
| I/O Method                    | How the editor receives I/O: //Standard// (stdin/stdout), //Socket// (TCP socket descriptor passed via drop file or argv), //FOSSIL// (BIOS int14h), //UART// (direct serial). |
| Use Shell or New Context      | If ''Yes'', launch via a shell. |
| Record Terminal Width         | Capture the user's terminal width into the message header so quoted reply formatting can match the original. |
| Word-wrap Quoted Text         | Word-wrap the user's terminal width when quoting. Options: ''No'', ''Yes, for terminal width'', ''Yes, for 79 columns''. |
| Retain Ctrl-A Codes in Quotes | If ''Yes'', preserve the original [[custom:ctrl-a_codes|Ctrl-A attribute codes]] when quoting; if ''No'', strip them. |
| Automatically Quoted Text     | What text the editor pre-loads as a quote: ''None'', ''All'' (the entire message being replied to), or ''Marked'' (only the marked region). |
| Editor Information Files      | What pre/post-edit drop files the editor expects: ''None'', ''WWIV EDITOR.INF/RESULT.ED'', or ''QuickBBS MSGTMP/MSGINF''. |
| Handle Soft CRs               | What to do with FidoNet-style "Soft CR" characters (''8Dh'') the editor inserts to mark word-wrapped lines: \\ \\ - **Unspecified** — system default (treat as Strip). \\ - **Convert to CRLF** — change Soft CRs to standard CRLF (hard line-breaks). \\ - **Strip (Remove)** — drop the Soft CRs and store long paragraphs as-is in the message base. \\ - **Retain (Leave in)** — leave 8Dh in the text like any other printable character. \\ \\ //N/A// when ''Support UTF-8 Encoding'' is ''Yes''. |
| Strip FidoNet Kludges         | If ''Yes'', remove FidoNet-style kludge lines (''^aMSGID:'' etc.) from quoted text. |
| Support UTF-8 Encoding        | If ''Yes'', the editor handles UTF-8 input and output correctly. |
| BBS Drop File Type            | Drop file format the editor needs (see [[#drop_file_types|Drop File Types]] below). Most modern editors don't need a drop file. |

===== Global Hot Key Events =====
A list of programs or loadable modules that can be executed by **anyone** on the BBS at **any time**, while the BBS has control of user input. Each binding ties one Ctrl-key to one [[config:cmdline|command line]].

Use ''Ins'' to add a binding, ''Del'' to remove one, or ''Enter'' to edit one. The hot-key trigger is a single uppercase letter; the BBS prepends Ctrl- (e.g. entering ''Y'' creates a Ctrl-Y trigger).

==== Hot Key Event ====

  ╔══════════════════════════════════════════════════════════╗
  ║                   Ctrl-Y Hot Key Event                   ║
  ╠══════════════════════════════════════════════════════════╣
  ║ │Global Hot Key             Ctrl-Y                       ║
  ║ │Command Line                                            ║
  ╚══════════════════════════════════════════════════════════╝

^ Option Name      ^ Description ^
| Global Hot Key   | The control key (e.g. ''Ctrl-Y'') that triggers this event. Pick a key not already consumed by another menu, prompt, or terminal-emulator shortcut. |
| Command Line     | The [[config:cmdline|command line]] to execute when the hot key is pressed. Supports the standard prefixes (e.g. ''?'' for [[dir:exec|exec]] JS, ''*'' for Baja) and command-line specifiers. |

:!: Hot keys fire wherever the BBS is reading input — at menus, prompts, message readers, etc. Choose carefully to avoid colliding with prompts that read a single keypress.

===== Online Programs (Doors) =====

A list of //Online Program Sections// configured for your system. A section is a sysop-defined grouping of programs (e.g. ''Main'', ''Games'', ''Operator'') with its own [[access:requirements|Access Requirements]]. Each section contains one or more online programs ([[howto:door:|doors]]).

Use ''Ins'' to add a section, ''Del'' to delete one (and all its programs), or ''Enter'' to configure one.

  ╔═════════════════════════════════════════════════╗
  ║  Online Program Sections               Programs ║
  ╠═════════════════════════════════════════════════╣
  ║ │Main                                         3 ║
  ║ │Games                                        1 ║
  ║ │Operator                                     8 ║
  ║ │                                               ║
  ╚═════════════════════════════════════════════════╝

==== Program Section ====

  ╔══════════════════════════════════════════════════════════╗
  ║                   Main Program Section                   ║
  ╠══════════════════════════════════════════════════════════╣
  ║ │Name                       Main                         ║
  ║ │Internal Code              MAIN                         ║
  ║ │Access Requirements                                     ║
  ║ │Online Programs...                                      ║
  ╚══════════════════════════════════════════════════════════╝

^ Option Name           ^ Description ^
| Name                  | Display name shown to users when they pick a program section. |
| Internal Code         | Up to 16 characters; uniquely identifies the section. Used in log files and as part of ARS expressions (e.g. ''XS GAMES''). |
| Access Requirements   | An [[access:requirements|ARS]] expression — only users matching the requirements see or enter this section. |
| Online Programs...    | Sub-menu listing the programs ([[howto:door:|doors]]) configured in this section (see [[#online_program|Online Program]] below). |

==== Online Program ====

The configuration menu for one online program (e.g. a [[howto:door:|door game]]). For detailed instructions on configuring BBS doors, see [[howto:door:]].

  ╔══════════════════════════════════════════════════════════╗
  ║                    BullsEye! Bulletins                   ║
  ╠══════════════════════════════════════════════════════════╣
  ║ │Name                       BullsEye! Bulletins          ║
  ║ │Internal Code              BULLSEYE                     ║
  ║ │Start-up Directory                                      ║
  ║ │Command Line               *bullseye                    ║
  ║ │Clean-up Command Line                                   ║
  ║ │Execution Cost             None                         ║
  ║ │Access Requirements                                     ║
  ║ │Execution Requirements                                  ║
  ║ │Multiple Concurrent Users  Yes                          ║
  ║ │Native Executable          No                           ║
  ║ │I/O Method                 Standard                     ║
  ║ │Use Shell or New Context   No                           ║
  ║ │Modify User Data           No                           ║
  ║ │Execute on Event           Logon                        ║
  ║ │Pause After Execution      No                           ║
  ║ │Disable Local Display      No                           ║
  ║ │BBS Drop File Type         None                         ║
  ║ │Place Drop File In         Node Directory               ║
  ║ │Time Options...                                         ║
  ╚══════════════════════════════════════════════════════════╝

^ Option Name              ^ Description ^
| Name                      | Display name shown to users in the program list. |
| Internal Code             | Up to 16 characters; uniquely identifies this program. Used in log files, in ''@-codes'' that auto-launch the program, and in [[module:str_cmds|EXEC]]-style commands. |
| Start-up Directory        | Working directory the program is launched in. Often the directory the door was installed into (e.g. ''/sbbs/xtrn/bullseye''). [[config:cmdline|Command-line specifiers]] are supported. |
| Command Line              | The [[config:cmdline|command line]] used to run the program. Standard prefixes (e.g. ''?'' for JavaScript, ''*'' for Baja, ''%!'' for the exec dir) and specifiers are supported. |
| Clean-up Command Line     | Optional second command line run **after** the program exits. Most often used by multi-user doors to release per-node state. |
| Execution Cost            | Number of [[access:credits|credits]] deducted from the user when running this program. ''0'' = free. |
| Access Requirements       | An [[access:requirements|ARS]] expression — only users matching it can **see** the program in menus. |
| Execution Requirements    | An [[access:requirements|ARS]] expression — users not matching it will see the program but be denied at run time. Use to expose programs for discovery while restricting actual play. |
| Multiple Concurrent Users | If ''Yes'', the program supports multiple simultaneous users (multi-node/multi-player door). |
| Native Executable         | ''Yes'' for native (non-DOS) executables; ''No'' for DOS programs. |
| I/O Method                | How the program receives client I/O: //Standard// (stdin/stdout — most JS/native), //Socket// (TCP socket descriptor), //FOSSIL// (BIOS int14h, classic DOS), //UART// (direct serial, classic DOS). |
| Use Shell or New Context  | If ''Yes'', launch via a shell (''/bin/sh -c'' on *nix, ''cmd /c'' on Windows). Required for command lines using shell features (pipes, redirection, glob). |
| Modify User Data          | If ''Yes'', Synchronet reads the program's drop file back when the user exits and applies the changes the program recorded there.  What can change depends on the ''BBS Drop File Type'' set for this program: \\ \\ - **DOOR.SYS** — security level, flag set #1, expiration date, total downloads, and kilobytes downloaded today; the 52-line variant can also adjust the user's time credits. \\ - **DORINFO#.DEF / DORINFO1.DEF** — ''EXITINFO.BBS'' is read for the security level and flag set #1. \\ - **PCBOARD.SYS** — ''USERS.SYS'' is read for the security level and expiration date. \\ - **Any other type** — ''MODUSER.DAT'' is read for a credit adjustment, a minute adjustment, security level, flag sets #1 through #4, exemptions, restrictions, and the expiration date. \\ \\ ''EXITINFO.BBS'' and ''MODUSER.DAT'' are deleted once read; ''DOOR.SYS'' and ''USERS.SYS'' are left in place.  No program can raise a user to sysop security level this way. |
| Execute on Event          | Optionally auto-run the program on a user-lifecycle event: //Logon//, //Logoff//, //New User//, //Birthday//, //Message Posted//, //File Uploaded//, //File Downloaded//, //Local/Sysop Chat//. After picking an event, you'll be prompted whether the program should also remain in the menu (''Execute as Event Only = No'') or be **only** an event hook (''Yes''). |
| Pause After Execution     | If ''Yes'', show ''[Hit a key]'' after the program exits — useful when the door prints info on exit, or for debugging misbehaving doors. |
| Disable Local Display     | If ''Yes'', suppress local-screen output during execution (sets ''Screen=NO'' in DOOR.SYS / PCBOARD.SYS; on Windows also stops a new console window from opening). |
| BBS Drop File Type        | Drop-file format the program expects (see [[#drop_file_types|Drop File Types]]). Most modern (Synchronet-aware) programs need ''None''. |
| Place Drop File In        | //Node Directory// (default, expected by classic XSDK doors), //Start-up Directory// (rarely safe for multi-user doors), or //Temp Directory// (per-node, cleared every logon — usually safest). |
| Time Options...           | Sub-menu (see [[#time_options|Time Options]]) for per-program time controls. |

==== Time Options ====

The Time Options sub-menu controls how Synchronet meters the user's time while the program runs.

  ╔════════════════════════════════════════╗
  ║      Online Program Time Options       ║
  ╠════════════════════════════════════════╣
  ║ │Extra Time               None         ║
  ║ │Maximum Time             None         ║
  ║ │Suspended (Free) Time    No           ║
  ║ │Monitor Time Left        No           ║
  ║ │Maximum Inactivity       None         ║
  ╚════════════════════════════════════════╝

^ Option Name              ^ Description ^
| Extra Time                | Minutes to **add** to the user's time-left while in the program. ''0'' = none. |
| Maximum Time              | If the program's drop file conveys time-left, this caps the value reported (so a user with hours of unused time doesn't get all of it inside this one program). ''0'' = no cap. |
| Suspended (Free) Time     | If ''Yes'', the user's online time clock is **suspended** while the program runs (free time). |
| Monitor Time Left         | If ''Yes'', Synchronet checks the user's time-left while the program runs and disconnects them if it reaches zero. If ''No'', only the program itself enforces time. |
| Maximum Inactivity        | Inactivity timeout for the client socket while the program runs. ''H''-exempt users are not disconnected. ''0'' = disabled (rely on the program itself to detect inactivity). |

===== Drop File Types =====

A //drop file// is a small text file Synchronet writes before executing a [[howto:door:|door]] or other external program, conveying caller and session information in a format the external program understands. Most BBS doors expect one of a handful of well-known formats.

The supported drop-file types (selected via //BBS Drop File Type// on each program) are:

^ Type             ^ Description ^
| None             | Synchronet does not write a drop file before invoking this program. |
| [[ref:xtrn.dat|XTRN.DAT]] | Synchronet-style drop file. |
| [[ref:chain.txt|CHAIN.TXT]] | WWIV-style drop file. |
| [[ref:door.sys|DOOR.SYS (31 lines)]] | The original 31-line GAP variant. |
| [[ref:door.sys|DOOR.SYS (52 lines)]] | The full 52-line standard. |
| DORINFO#.DEF     | RemoteAccess-style numbered per-node (e.g. ''DORINFO2.DEF'' for node 2). |
| [[ref:dorinfo1.def|DORINFO1.DEF]] | RemoteAccess-style with the filename always ''DORINFO1.DEF'' regardless of node. |
| [[ref:callinfo.bbs|CALLINFO.BBS]] | Wildcat! style. |
| [[ref:pcboard.sys|PCBOARD.SYS]] | PCBoard style. |
| SFDOORS.DAT      | Spitfire BBS style. |
| DOORFILE.SR      | RemoteAccess SR-style. |
| TRIBBS.SYS       | TriBBS style. |
| DOOR32.SYS       | The modern cross-BBS standard for door interchange ([[https://github.com/NuSkooler/enigma-bbs/blob/master/docs/modding/doors.md#door32sys|spec]]). Recommended for new door development. |

The //Place Drop File In// field selects the directory the file is written to:
  * **Node Directory** — the per-node ''[[dir:node]]'' directory (default; appropriate for most doors).
  * **Start-up Directory** — the program's configured start-up directory (use when the door expects the file alongside its own files).
  * **Other** — a sysop-specified path.


===== See Also =====
  * [[:config:|config index]]

{{tag>door event editor}}
