View source with raw comments or as raw
    1/*  Part of SWI-Prolog
    2
    3    Author:        Jan Wielemaker & Steve Prior
    4    E-mail:        J.Wielemaker@vu.nl
    5    WWW:           http://www.swi-prolog.org
    6    Copyright (c)  2004-2011, University of Amsterdam
    7                              VU University Amsterdam
    8    All rights reserved.
    9
   10    Redistribution and use in source and binary forms, with or without
   11    modification, are permitted provided that the following conditions
   12    are met:
   13
   14    1. Redistributions of source code must retain the above copyright
   15       notice, this list of conditions and the following disclaimer.
   16
   17    2. Redistributions in binary form must reproduce the above copyright
   18       notice, this list of conditions and the following disclaimer in
   19       the documentation and/or other materials provided with the
   20       distribution.
   21
   22    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   23    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   24    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   25    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   26    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   27    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   28    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   29    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   30    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   32    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   33    POSSIBILITY OF SUCH DAMAGE.
   34*/
   35
   36:- module(prolog_server,
   37          [ prolog_server/2             % +Port, +Options
   38          ]).   39
   40:- use_module(library(socket)).
 prolog_server(?Port, +Options)
Create a TCP/IP based server on the given Port, so you can telnet into Prolog and run an interactive session. This library is intended to provide access for debugging and management of embedded servers.

Currently defined options are:

allow(IP)
Allow access from IP, a term of the format ip(A,B,C,D). Multiple of such terms can exist and access is granted if the peer IP address unifies to one of them. If no allow option is provided access is only granted from ip(127,0,0,1) (localhost).

For example:

?- prolog_server(4000, []).

% telnet localhost 4000
Welcome to the SWI-Prolog server on thread 3

1 ?-
bug
- As the connection does not involve a terminal, command history and completion are not provided. Neither are interrupts (Control-C). To terminate the Prolog shell one must enter the command "end_of_file."
   75prolog_server(Port, Options) :-
   76    tcp_socket(ServerSocket),
   77    tcp_setopt(ServerSocket, reuseaddr),
   78    tcp_bind(ServerSocket, Port),
   79    tcp_listen(ServerSocket, 5),
   80    thread_create(server_loop(ServerSocket, Options), _,
   81                  [ alias(prolog_server)
   82                  ]).
   83
   84server_loop(ServerSocket, Options) :-
   85    tcp_accept(ServerSocket, Slave, Peer),
   86    tcp_open_socket(Slave, InStream, OutStream),
   87    set_stream(InStream, close_on_abort(false)),
   88    set_stream(OutStream, close_on_abort(false)),
   89    tcp_host_to_address(Host, Peer),
   90    (   Postfix = []
   91    ;   between(2, 1000, Num),
   92        Postfix = [-, Num]
   93    ),
   94    atomic_list_concat(['client@', Host | Postfix], Alias),
   95    catch(thread_create(
   96              service_client(InStream, OutStream, Peer, Options),
   97              _,
   98              [ alias(Alias)
   99              ]),
  100          error(permission_error(create, thread, Alias), _),
  101          fail),
  102    !,
  103    server_loop(ServerSocket, Options).
  104
  105service_client(InStream, OutStream, Peer, Options) :-
  106    allow(Peer, Options),
  107    !,
  108    thread_self(Id),
  109    set_prolog_IO(InStream, OutStream, OutStream),
  110    set_stream(InStream, tty(true)),
  111    set_prolog_flag(tty_control, false),
  112    current_prolog_flag(encoding, Enc),
  113    set_stream(user_input, encoding(Enc)),
  114    set_stream(user_output, encoding(Enc)),
  115    set_stream(user_error, encoding(Enc)),
  116    set_stream(user_input, newline(detect)),
  117    set_stream(user_output, newline(dos)),
  118    set_stream(user_error, newline(dos)),
  119    format(user_error,
  120           'Welcome to the SWI-Prolog server on thread ~w~n~n',
  121           [Id]),
  122    call_cleanup(prolog,
  123                 ( close(InStream),
  124                   close(OutStream),
  125                   thread_detach(Id))).
  126service_client(InStream, OutStream, _, _):-
  127    thread_self(Id),
  128    format(OutStream, 'Go away!!~n', []),
  129    close(InStream),
  130    close(OutStream),
  131    thread_detach(Id).
  132
  133
  134allow(Peer, Options) :-
  135    (   member(allow(Allow), Options)
  136    *-> Peer = Allow,
  137        !
  138    ;   Peer = ip(127,0,0,1)
  139    )