aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Touhey <thomas@touhey.fr>2019-09-07 12:38:18 +0200
committerThomas Touhey <thomas@touhey.fr>2019-09-07 12:38:18 +0200
commit6efc262a69d99a4e94d401810eece94fc3392b56 (patch)
tree388cc92c31fc1779fed9d580c9df12a500997f20
parentb9b1ac627dfc18c89de5a678bdee218718800783 (diff)
Latest updates.
-rw-r--r--.plan2
-rw-r--r--LICENSE.txt18
-rw-r--r--README.rst9
-rw-r--r--docs/.python-version1
-rw-r--r--docs/Makefile16
-rw-r--r--docs/Pipfile13
-rw-r--r--docs/Pipfile.lock225
-rw-r--r--docs/conf.py16
-rw-r--r--docs/configure.rst (renamed from docs/running.rst)98
-rw-r--r--docs/favicon.pngbin0 -> 17554 bytes
-rw-r--r--docs/index.rst4
-rw-r--r--docs/run.rst13
-rwxr-xr-xfingerd/__init__.py9
-rwxr-xr-xfingerd/__main__.py6
-rwxr-xr-xfingerd/_binds.py17
-rwxr-xr-xfingerd/_exceptions.py6
-rwxr-xr-xfingerd/_fiction.py41
-rwxr-xr-xfingerd/_server.py35
-rwxr-xr-xfingerd/_util.py16
-rwxr-xr-xfingerd/control/__init__.py10
-rwxr-xr-xfingerd/control/__main__.py6
-rwxr-xr-xscripts/fingerd6
-rwxr-xr-xscripts/fingerd-control6
-rwxr-xr-xsetup.py4
24 files changed, 433 insertions, 144 deletions
diff --git a/.plan b/.plan
index 7e09d1b..b98b699 100644
--- a/.plan
+++ b/.plan
@@ -6,5 +6,5 @@
yet another |___/ finger daemon
Find out more about the project on
- https://forge.touhey.fr/fingerd.git
+ https://fingerd.touhey.pro/
diff --git a/LICENSE.txt b/LICENSE.txt
index 2b2178c..521e167 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -3,12 +3,12 @@ The MIT License (MIT)
Copyright (C) 2017-2019 Thomas Touhey <thomas@touhey.fr>
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the “Software”), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the “Software”),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
@@ -17,6 +17,6 @@ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-IN THE SOFTWARE.
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/README.rst b/README.rst
index 2dd6578..07c8e46 100644
--- a/README.rst
+++ b/README.rst
@@ -7,8 +7,9 @@ in 1977, then in `RFC 1288`_ in 1991, and has been abandoned since.
While describing the protocol in `a blog post of mine`_, I wanted
to implement this protocol for fun, but didn't want to present the
-real information about the users on my server, so I made this to present some
-fictional information in order to be able to tell a story through finger.
+real information about the users on my server, so I made this to present
+some fictional information in order to be able to tell a story through
+finger.
Find out more on `the fingerd homepage <https://fingerd.touhey.pro/>`_.
@@ -24,8 +25,8 @@ For v0.2:
For further versions:
-- add a live action interface (where a port/socket is opened and updates are
- read and applied through it).
+- add a live action interface (where a port/socket is opened and updates
+ are read and applied through it).
- add a POSIX native interface.
.. _RFC 742: https://tools.ietf.org/html/rfc742
diff --git a/docs/.python-version b/docs/.python-version
new file mode 100644
index 0000000..0b2eb36
--- /dev/null
+++ b/docs/.python-version
@@ -0,0 +1 @@
+3.7.2
diff --git a/docs/Makefile b/docs/Makefile
index 08157af..ebf70c7 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -2,13 +2,15 @@
#
# You can set these variables from the command line.
+
+PE = pipenv run
SPHINXOPTS =
-SPHINXBUILD = sphinx-build
+SPHINXBUILD = $(PE) sphinx-build
+SPHINXWATCH = $(PE) sphinx-autobuild
SPHINXPROJ = textoutpc
SOURCEDIR = .
BUILDDIR = _build
-
-WEBROOT := fingerd.touhey.pro:fingerd_doc
+WEBROOT = fingerd.touhey.pro:fingerd_doc
# Put it first so that "make" without argument is like "make help".
help:
@@ -23,9 +25,15 @@ help:
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+# Livehtml build.
+livehtml:
+ $(SPHINXWATCH) -b html $(SPHINXOPTS) . $(BUILDDIR)/html
+
+.PHONY: livehtml
+
# Send the website content (Linux-only).
show: html
find _build/html -type f -exec chmod 644 {} \;
rsync -Prlt --delete _build/html/ "$(WEBROOT)"
-.PHONY: show \ No newline at end of file
+.PHONY: show
diff --git a/docs/Pipfile b/docs/Pipfile
new file mode 100644
index 0000000..57a81a3
--- /dev/null
+++ b/docs/Pipfile
@@ -0,0 +1,13 @@
+[[source]]
+name = "pypi"
+url = "https://pypi.org/simple"
+verify_ssl = true
+
+[dev-packages]
+
+[packages]
+sphinx = "*"
+sphinx-rtd-theme = "*"
+
+[requires]
+python_version = "3.7"
diff --git a/docs/Pipfile.lock b/docs/Pipfile.lock
new file mode 100644
index 0000000..22db0bb
--- /dev/null
+++ b/docs/Pipfile.lock
@@ -0,0 +1,225 @@
+{
+ "_meta": {
+ "hash": {
+ "sha256": "ad49cdffc75c09b6abfb00f80a96f9c4967858dfc7153f34febb993592308482"
+ },
+ "pipfile-spec": 6,
+ "requires": {
+ "python_version": "3.7"
+ },
+ "sources": [
+ {
+ "name": "pypi",
+ "url": "https://pypi.org/simple",
+ "verify_ssl": true
+ }
+ ]
+ },
+ "default": {
+ "alabaster": {
+ "hashes": [
+ "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359",
+ "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"
+ ],
+ "version": "==0.7.12"
+ },
+ "babel": {
+ "hashes": [
+ "sha256:af92e6106cb7c55286b25b38ad7695f8b4efb36a90ba483d7f7a6628c46158ab",
+ "sha256:e86135ae101e31e2c8ec20a4e0c5220f4eed12487d5cf3f78be7e98d3a57fc28"
+ ],
+ "version": "==2.7.0"
+ },
+ "certifi": {
+ "hashes": [
+ "sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5",
+ "sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae"
+ ],
+ "version": "==2019.3.9"
+ },
+ "chardet": {
+ "hashes": [
+ "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
+ "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
+ ],
+ "version": "==3.0.4"
+ },
+ "docutils": {
+ "hashes": [
+ "sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
+ "sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274",
+ "sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"
+ ],
+ "version": "==0.14"
+ },
+ "idna": {
+ "hashes": [
+ "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
+ "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
+ ],
+ "version": "==2.8"
+ },
+ "imagesize": {
+ "hashes": [
+ "sha256:3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8",
+ "sha256:f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5"
+ ],
+ "version": "==1.1.0"
+ },
+ "jinja2": {
+ "hashes": [
+ "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013",
+ "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b"
+ ],
+ "version": "==2.10.1"
+ },
+ "markupsafe": {
+ "hashes": [
+ "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
+ "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
+ "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
+ "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
+ "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
+ "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
+ "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
+ "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
+ "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
+ "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
+ "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
+ "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
+ "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
+ "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
+ "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
+ "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
+ "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
+ "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
+ "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
+ "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
+ "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
+ "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
+ "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
+ "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
+ "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
+ "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
+ "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
+ "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"
+ ],
+ "version": "==1.1.1"
+ },
+ "packaging": {
+ "hashes": [
+ "sha256:0c98a5d0be38ed775798ece1b9727178c4469d9c3b4ada66e8e6b7849f8732af",
+ "sha256:9e1cbf8c12b1f1ce0bb5344b8d7ecf66a6f8a6e91bcb0c84593ed6d3ab5c4ab3"
+ ],
+ "version": "==19.0"
+ },
+ "pygments": {
+ "hashes": [
+ "sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127",
+ "sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"
+ ],
+ "version": "==2.4.2"
+ },
+ "pyparsing": {
+ "hashes": [
+ "sha256:1873c03321fc118f4e9746baf201ff990ceb915f433f23b395f5580d1840cb2a",
+ "sha256:9b6323ef4ab914af344ba97510e966d64ba91055d6b9afa6b30799340e89cc03"
+ ],
+ "version": "==2.4.0"
+ },
+ "pytz": {
+ "hashes": [
+ "sha256:303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda",
+ "sha256:d747dd3d23d77ef44c6a3526e274af6efeb0a6f1afd5a69ba4d5be4098c8e141"
+ ],
+ "version": "==2019.1"
+ },
+ "requests": {
+ "hashes": [
+ "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
+ "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"
+ ],
+ "version": "==2.22.0"
+ },
+ "six": {
+ "hashes": [
+ "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
+ "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
+ ],
+ "version": "==1.12.0"
+ },
+ "snowballstemmer": {
+ "hashes": [
+ "sha256:919f26a68b2c17a7634da993d91339e288964f93c274f1343e3bbbe2096e1128",
+ "sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89"
+ ],
+ "version": "==1.2.1"
+ },
+ "sphinx": {
+ "hashes": [
+ "sha256:423280646fb37944dd3c85c58fb92a20d745793a9f6c511f59da82fa97cd404b",
+ "sha256:de930f42600a4fef993587633984cc5027dedba2464bcf00ddace26b40f8d9ce"
+ ],
+ "index": "pypi",
+ "version": "==2.0.1"
+ },
+ "sphinx-rtd-theme": {
+ "hashes": [
+ "sha256:00cf895504a7895ee433807c62094cf1e95f065843bf3acd17037c3e9a2becd4",
+ "sha256:728607e34d60456d736cc7991fd236afb828b21b82f956c5ea75f94c8414040a"
+ ],
+ "index": "pypi",
+ "version": "==0.4.3"
+ },
+ "sphinxcontrib-applehelp": {
+ "hashes": [
+ "sha256:edaa0ab2b2bc74403149cb0209d6775c96de797dfd5b5e2a71981309efab3897",
+ "sha256:fb8dee85af95e5c30c91f10e7eb3c8967308518e0f7488a2828ef7bc191d0d5d"
+ ],
+ "version": "==1.0.1"
+ },
+ "sphinxcontrib-devhelp": {
+ "hashes": [
+ "sha256:6c64b077937330a9128a4da74586e8c2130262f014689b4b89e2d08ee7294a34",
+ "sha256:9512ecb00a2b0821a146736b39f7aeb90759834b07e81e8cc23a9c70bacb9981"
+ ],
+ "version": "==1.0.1"
+ },
+ "sphinxcontrib-htmlhelp": {
+ "hashes": [
+ "sha256:4670f99f8951bd78cd4ad2ab962f798f5618b17675c35c5ac3b2132a14ea8422",
+ "sha256:d4fd39a65a625c9df86d7fa8a2d9f3cd8299a3a4b15db63b50aac9e161d8eff7"
+ ],
+ "version": "==1.0.2"
+ },
+ "sphinxcontrib-jsmath": {
+ "hashes": [
+ "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178",
+ "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"
+ ],
+ "version": "==1.0.1"
+ },
+ "sphinxcontrib-qthelp": {
+ "hashes": [
+ "sha256:513049b93031beb1f57d4daea74068a4feb77aa5630f856fcff2e50de14e9a20",
+ "sha256:79465ce11ae5694ff165becda529a600c754f4bc459778778c7017374d4d406f"
+ ],
+ "version": "==1.0.2"
+ },
+ "sphinxcontrib-serializinghtml": {
+ "hashes": [
+ "sha256:c0efb33f8052c04fd7a26c0a07f1678e8512e0faec19f4aa8f2473a8b81d5227",
+ "sha256:db6615af393650bf1151a6cd39120c29abaf93cc60db8c48eb2dddbfdc3a9768"
+ ],
+ "version": "==1.1.3"
+ },
+ "urllib3": {
+ "hashes": [
+ "sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1",
+ "sha256:dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232"
+ ],
+ "version": "==1.25.3"
+ }
+ },
+ "develop": {}
+}
diff --git a/docs/conf.py b/docs/conf.py
index bef60d2..5b882e0 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -23,11 +23,17 @@ project = 'fingerd'
copyright = '2019, Thomas Touhey'
author = 'Thomas Touhey'
-# The short X.Y version
-version = ''
# The full version, including alpha/beta/rc tags
-release = ''
+def _get_release():
+ from os.path import dirname, join
+ from pkg_resources import find_distributions as find_dist
+
+ module_path = join(dirname(__file__), '..')
+ dist = next(find_dist(module_path, True))
+ return dist.version
+
+release = _get_release()
# -- General configuration ---------------------------------------------------
@@ -39,6 +45,7 @@ release = ''
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
+ 'sphinx.ext.autodoc'
]
# Add any paths that contain templates here, relative to this directory.
@@ -71,6 +78,9 @@ pygments_style = 'sphinx'
# -- Options for HTML output -------------------------------------------------
+html_baseurl = "/docs"
+html_favicon = "favicon.png"
+
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
diff --git a/docs/running.rst b/docs/configure.rst
index be6cbce..978d848 100644
--- a/docs/running.rst
+++ b/docs/configure.rst
@@ -1,19 +1,5 @@
-Configuring and running fingerd
-===============================
-
-``fingerd`` can be run directly and without configuration (while taking its
-default option values) with the following command:
-
-.. code-block:: sh
-
- python3 -m fingerd <command line options>
-
-The server will run while giving native information on TCP port 79 on both
-IPv4 and IPv6 (if available). However, you can tweak this behaviour by
-configuring it.
-
-Configuration
--------------
+Configuring fingerd
+===================
``fingerd`` stores its configuration in the environment. For commodity,
a ``.env`` configuration is proposed, install the ``python-dotenv`` module
@@ -45,8 +31,17 @@ its comments.
``[::1:2:3:4]:1234``
Bind on ``::1:2:3:4`` (IPv6) port 1234.
- For example, ``localhost`` usually binds on ``127.0.0.1:79`` (IPv4) and
- ``[::1]:79`` (IPv6).
+ Here are some examples:
+
+ .. code-block:: bash
+
+ # On modern platforms, binds on 127.0.0.1:79 (IPv4)
+ # and [::1]:79 (IPv6).
+ BIND=localhost
+
+ # Binds on 1.2.3.4:3331 and [2001:41d0:302:2200::3b2]:79.
+ BIND="1.2.3.4:3331,[2001:41d0:302:2200::3b2]:79"
+ BIND="1.2.3.4:3331,2001:41d0:302:2200::3b2"
``FINGER_HOST``
The host as which fingerd identifies itself (domain name), ``LOCALHOST``
@@ -63,7 +58,7 @@ its comments.
The data is gathered from the system.
``SCENARIO``
- The data is gathered from a scenario (see :ref:`actions` below).
+ The data is gathered from a scenario (see :ref:`scenario` below).
``LIVE``
The data is gathered from actions given in an IPC endpoint (see
@@ -109,33 +104,11 @@ requests from the same machine (on IPv4 and IPv6):
.. _actions:
-Scenarios
-~~~~~~~~~
+Actions
+-------
-Scenarios are TOML documents describing actions, which are points in time
-where something happens. Every action has a time offset, using a TOML
-array section (``[[something]]``), and properties describing what's
-happening. Time offsets are represented the following way:
-
-::
-
- -?(<weeks>w)?(<days>[jd])?(<hours>h)?(<minutes>m)?(<seconds>s)?
-
-Where negative times, starting with a dash (``-``), are the initial situation,
-what is supposed to have happened before the beginning.
-
-For example, ``-1w5d2h`` means “1 week, 5 days and 2 hours before the
-origin” and ``2j`` means “2 days after the origin”. So if we want to make
-an action that takes place 5 seconds after the origin, the first line of the
-action will be the following one:
-
-.. code-block::
-
- [[5s]]
-
-All actions have a type represented by the ``type`` property, and other
-properties depending on the type. Types and related properties are
-described in the sections below.
+While interfaces provide still information to the server, some use actions
+underneath. In this section, the actions themselves are described.
Flow-related actions
~~~~~~~~~~~~~~~~~~~~
@@ -217,9 +190,42 @@ The ``login`` operation takes the information about the originating shell:
``host``
The remote host from which the physical line is opened, if any.
+.. _scenario:
+
+Scenario (scripted actions)
+---------------------------
+
+Scenarios, represented by the ``SCENARIO`` server type, are scripted
+sequences of actions.
+
+Scenarios use a TOML document describing actions, which are points in time
+where something happens. Every action has a time offset, using a TOML
+array section (``[[something]]``), and properties describing what's
+happening. Time offsets are represented the following way:
+
+::
+
+ -?(<weeks>w)?(<days>[jd])?(<hours>h)?(<minutes>m)?(<seconds>s)?
+
+Where negative times, starting with a dash (``-``), are the initial situation,
+what is supposed to have happened before the beginning.
+
+For example, ``-1w5d2h`` means “1 week, 5 days and 2 hours before the
+origin” and ``2j`` means “2 days after the origin”. So if we want to make
+an action that takes place 5 seconds after the origin, the first line of the
+action will be the following one:
+
+.. code-block::
+
+ [[5s]]
+
+All actions have a type represented by the ``type`` property, and other
+properties depending on the type. Types and related properties are
+described in the :ref:`actions` section.
+
.. _live:
Live actions
-~~~~~~~~~~~~
+------------
TODO
diff --git a/docs/favicon.png b/docs/favicon.png
new file mode 100644
index 0000000..034a14a
--- /dev/null
+++ b/docs/favicon.png
Binary files differ
diff --git a/docs/index.rst b/docs/index.rst
index 789ba2b..0ec0706 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -10,9 +10,9 @@ project homepage at `fingerd.touhey.pro <https://fingerd.touhey.pro/>`_!
.. toctree::
:maxdepth: 2
- :caption: Contents:
- running
+ run
+ configure
.. _RFC 742: https://tools.ietf.org/html/rfc742
.. _RFC 1288: https://tools.ietf.org/html/rfc1288
diff --git a/docs/run.rst b/docs/run.rst
new file mode 100644
index 0000000..3204d16
--- /dev/null
+++ b/docs/run.rst
@@ -0,0 +1,13 @@
+Running fingerd
+===============
+
+``fingerd`` can be run directly and without configuration (while taking its
+default option values) with the following command:
+
+.. code-block:: sh
+
+ python3 -m fingerd <command line options>
+
+The server will run while giving native information on TCP port 79 on both
+IPv4 and IPv6 (if available). However, you can tweak this behaviour by
+configuring it.
diff --git a/fingerd/__init__.py b/fingerd/__init__.py
index dc7dd17..aa779a9 100755
--- a/fingerd/__init__.py
+++ b/fingerd/__init__.py
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
-#******************************************************************************
+#**************************************************************************
# Copyright (C) 2017-2019 Thomas Touhey <thomas@touhey.fr>
-# This file is part of the fingerd Python 3.x module, which is MIT-licensed.
-#******************************************************************************
+# This file is part of the fingerd project, which is MIT-licensed.
+#**************************************************************************
""" finger is both a protocol and a utility to get the information and
status from a user on a distant machine. It was standardized in RFC 742
in 1977, then in RFC 1288 in 1991, and has been abandoned by most
@@ -55,7 +55,8 @@ except (ImportError, ModuleNotFoundError):
# ---
def _get_server():
- """ Get the server through the configuration stored in the environment. """
+ """ Get the server through the configuration stored in the
+ environment. """
# Load the .env file if present.
diff --git a/fingerd/__main__.py b/fingerd/__main__.py
index 97a3dbe..57714f5 100755
--- a/fingerd/__main__.py
+++ b/fingerd/__main__.py
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
-#******************************************************************************
+#**************************************************************************
# Copyright (C) 2017-2019 Thomas Touhey <thomas@touhey.fr>
-# This file is part of the fingerd Python 3.x module, which is MIT-licensed.
-#******************************************************************************
+# This file is part of the fingerd project, which is MIT-licensed.
+#**************************************************************************
""" Main script of the module.
Runs the server depending on the configuration content. """
diff --git a/fingerd/_binds.py b/fingerd/_binds.py
index a4ea7d4..ac391f3 100755
--- a/fingerd/_binds.py
+++ b/fingerd/_binds.py
@@ -1,15 +1,16 @@
#!/usr/bin/env python3
-#******************************************************************************
+#**************************************************************************
# Copyright (C) 2017-2019 Thomas Touhey <thomas@touhey.fr>
-# This file is part of the fingerd Python 3.x module, which is MIT-licensed.
-#******************************************************************************
+# This file is part of the fingerd project, which is MIT-licensed.
+#**************************************************************************
""" This file serves for managing binds. """
from enum import Enum as _Enum
import socket as _socket
-from ._exceptions import InvalidBindAddressError as _InvalidBindAddressError
+from ._exceptions import \
+ InvalidBindAddressError as _InvalidBindAddressError
__all__ = ["BindAddressType", "BindsDecoder"]
@@ -190,8 +191,8 @@ def _decode_tcp_host(x):
class BindsDecoder:
""" Binds decoder for fingerd.
Takes a raw string and the protocol name, either 'finger' (the base
- protocol managed by the class) or 'fingerd-control' (the protocol used
- for controlling the live fingerd interface). """
+ protocol managed by the class) or 'fingerd-control' (the protocol
+ used for controlling the live fingerd interface). """
def __init__(self, raw, proto = 'finger'):
proto = proto.casefold()
@@ -218,8 +219,8 @@ class BindsDecoder:
if (proto == 'finger' and scheme != 'tcp') \
or scheme not in ('tcp', 'ipc'):
- raise _InvalidBindError("unsupported scheme {repr(scheme)} " \
- f"for protocol {repr(proto)}")
+ raise _InvalidBindError("unsupported scheme "
+ f"{repr(scheme)} for protocol {repr(proto)}")
# Decode the address data.
diff --git a/fingerd/_exceptions.py b/fingerd/_exceptions.py
index 0d03e6f..a2ecdd0 100755
--- a/fingerd/_exceptions.py
+++ b/fingerd/_exceptions.py
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
-#******************************************************************************
+#**************************************************************************
# Copyright (C) 2017-2019 Thomas Touhey <thomas@touhey.fr>
-# This file is part of the fingerd Python 3.x module, which is MIT-licensed.
-#******************************************************************************
+# This file is part of the fingerd project, which is MIT-licensed.
+#**************************************************************************
""" This file defines the exceptions used throughout the module. """
class ConfigurationError(Exception):
diff --git a/fingerd/_fiction.py b/fingerd/_fiction.py
index 2b71640..b2bec47 100755
--- a/fingerd/_fiction.py
+++ b/fingerd/_fiction.py
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
-#******************************************************************************
+#**************************************************************************
# Copyright (C) 2017-2019 Thomas Touhey <thomas@touhey.fr>
-# This file is part of the fingerd Python 3.x module, which is MIT-licensed.
-#******************************************************************************
+# This file is part of the fingerd project, which is MIT-licensed.
+#**************************************************************************
""" Definitions for the finger server fiction interface.
This file contains everything to decode and use the actions file. """
@@ -14,7 +14,8 @@ from datetime import datetime as _dt, timedelta as _td
from ._util import FingerInterface as _FingerInterface, \
FingerUser as _FingerUser, FingerSession as _FingerSession
-__all__ = ["FingerFictionInterface", "FingerLiveInterface", "FingerFiction"]
+__all__ = ["FingerFictionInterface", "FingerLiveInterface",
+ "FingerFiction"]
_toml = None
@@ -224,7 +225,8 @@ class _UserLoginAction(_Action):
self.__session = session
def __repr__(self):
- p = (f"{x} = {repr(getattr(self, x))}" for x in ('login', 'session'))
+ p = (f"{x} = {repr(getattr(self, x))}" for x in ('login',
+ 'session'))
return f"{self.__class__.__name__}({', '.join(p)})"
@property
@@ -273,7 +275,7 @@ class _UserIdleToggleAction(_Action):
self.__idle = bool(idle)
def __repr__(self):
- p = (f"{x} = {repr(getattr(self, x))}" for x in ('login', 'name', \
+ p = (f"{x} = {repr(getattr(self, x))}" for x in ('login', 'name',
'idle'))
return f"{self.__class__.__name__}({', '.join(p)})"
@@ -329,7 +331,8 @@ class FingerFiction:
try:
import toml
except ModuleNotFoundError:
- raise ModuleNotFoundError("'toml' module required") from None
+ raise ModuleNotFoundError("'toml' module "
+ "required") from None
_toml = toml
del toml
@@ -429,7 +432,8 @@ class FingerFiction:
if data['plan'] is False:
plan = None
else:
- pp = _path.join(_path.dirname(path), data['plan'])
+ pp = _path.join(_path.dirname(path),
+ data['plan'])
plan = open(pp).read()
action = _UserEditionAction(login, name, home, shell,
@@ -545,7 +549,8 @@ class _FingerFictionalInterface(_FingerInterface):
""" Look for users according to a check. """
self.update()
- return [_copy.deepcopy(u) for u in self.__users.values() if check(u)]
+ return [_copy.deepcopy(u) for u in self.__users.values() \
+ if check(u)]
def reset(self):
""" Reset the interface (revert all actions). """
@@ -571,7 +576,7 @@ class _FingerFictionalInterface(_FingerInterface):
if action.login is None:
raise ValueError("missing login")
if not action.login in self.__users:
- raise ValueError("got no user with login " \
+ raise ValueError("got no user with login "
f"{repr(action.login)}")
user = self.__users[action.login]
@@ -591,7 +596,7 @@ class _FingerFictionalInterface(_FingerInterface):
if action.login is None:
raise ValueError("missing login")
if not action.login in self.__users:
- raise ValueError("got no user with login " \
+ raise ValueError("got no user with login "
f"{repr(action.login)}")
del self.__users[action.login]
@@ -607,7 +612,7 @@ class _FingerFictionalInterface(_FingerInterface):
try:
user = self.__users[action.login]
except KeyError:
- raise ValueError("got no user with login " \
+ raise ValueError("got no user with login "
f"{repr(action.login)}") from None
user.sessions.add(session)
@@ -627,7 +632,7 @@ class _FingerFictionalInterface(_FingerInterface):
try:
del user.sessions[action.name]
except (KeyError, IndexError):
- raise ValueError(f"got no session {repr(action.name)} " \
+ raise ValueError(f"got no session {repr(action.name)} "
f"for user {repr(action.login)}") from None
elif isinstance(action, _UserIdleToggleAction):
# Make user with login `action.login` idle.
@@ -644,7 +649,7 @@ class _FingerFictionalInterface(_FingerInterface):
try:
session = user.sessions[action.name]
except (KeyError, IndexError):
- raise ValueError(f"got no session {repr(action.name)} " \
+ raise ValueError(f"got no session {repr(action.name)} "
f"for user {repr(action.login)}") from None
since = self.__start + time
@@ -679,8 +684,8 @@ class FingerFictionInterface(_FingerFictionalInterface):
if isinstance(fiction, FingerFiction):
self.__as = _copy.copy(fiction)
elif fiction is not None:
- raise TypeError("fiction should be a FingerFiction or None, is " \
- f"{fiction.__class__.__name__}.")
+ raise TypeError("fiction should be a FingerFiction or None, "
+ f"is {fiction.__class__.__name__}.")
# Initialize the object properties.
# - `fiction`: the script to follow.
@@ -716,8 +721,8 @@ class FingerFictionInterface(_FingerFictionalInterface):
time = self.__get_time()
if self.__fiction is not None:
- # Check if we need to reset (no users left and apply the actions
- # from before the start).
+ # Check if we need to reset (no users left and apply the
+ # actions from before the start).
if self.__current is None or self.__current > time:
self.reset()
diff --git a/fingerd/_server.py b/fingerd/_server.py
index 3833837..01cb4e1 100755
--- a/fingerd/_server.py
+++ b/fingerd/_server.py
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
-#******************************************************************************
+#**************************************************************************
# Copyright (C) 2017-2019 Thomas Touhey <thomas@touhey.fr>
-# This file is part of the fingerd Python 3.x module, which is MIT-licensed.
-#******************************************************************************
+# This file is part of the fingerd project, which is MIT-licensed.
+#**************************************************************************
""" The main server class for the server, with the related utilities that
will not be presented to the user, is defined in this file. """
@@ -13,8 +13,9 @@ from io import TextIOWrapper as _TextIOWrapper, StringIO as _StringIO
from ._util import (FingerInterface as _FingerInterface,
FingerFormatter as _FingerFormatter, FingerLogger as _FingerLogger,
- ConfigurationError as _InvalidConfError, BindError as _InvalidBindError,
- BindAddressType as _BindAddressType, BindsDecoder as _BindsDecoder)
+ ConfigurationError as _InvalidConfError,
+ BindError as _InvalidBindError, BindAddressType as _BindAddressType,
+ BindsDecoder as _BindsDecoder)
__all__ = ["FingerServer"]
@@ -35,11 +36,11 @@ class _FingerQuery:
verbose (this token can be ignored). """
# "By default, this program SHOULD filter any unprintable data,
- # leaving only printable 7-bit characters (ASCII 32 through ASCII 126),
- # tabs (ASCII 9) and CRLFs."
+ # leaving only printable 7-bit characters (ASCII 32 through
+ # ASCII 126), tabs (ASCII 9) and CRLFs."
- allowed_chars = "\t !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" \
- + _string.ascii_letters + _string.digits
+ allowed_chars = ("\t !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
+ + _string.ascii_letters + _string.digits)
def __init__(self, raw):
""" Initialize the query object by decoding the data. """
@@ -78,8 +79,8 @@ class _FingerTCPHandler(_socketserver.StreamRequestHandler):
def handle(self):
""" Request handling. """
- inp = _TextIOWrapper(self.rfile, encoding = 'ascii', errors = 'ignore',
- newline = '\r\n')
+ inp = _TextIOWrapper(self.rfile, encoding = 'ascii',
+ errors = 'ignore', newline = '\r\n')
outp = _TextIOWrapper(self.wfile, encoding = 'ascii')
# Gather the request line.
@@ -186,7 +187,8 @@ class _FingerTCPHandler(_socketserver.StreamRequestHandler):
# TCP servers.
# ---
-class _IPv4TCPServer(_socketserver.ThreadingMixIn, _socketserver.TCPServer):
+class _IPv4TCPServer(_socketserver.ThreadingMixIn,
+ _socketserver.TCPServer):
""" The IPv4 TCP Server to be used """
address_family = _socket.AF_INET
@@ -196,7 +198,8 @@ class _IPv4TCPServer(_socketserver.ThreadingMixIn, _socketserver.TCPServer):
self.params = params
super().__init__(*args, **kwargs)
-class _IPv6TCPServer(_socketserver.ThreadingMixIn, _socketserver.TCPServer):
+class _IPv6TCPServer(_socketserver.ThreadingMixIn,
+ _socketserver.TCPServer):
""" The IPv6 TCP Server to be used """
address_family = _socket.AF_INET6
@@ -252,13 +255,13 @@ class FingerServer:
# Check the interface and formatter classes.
if not isinstance(interface, _FingerInterface):
- raise InvalidConfigurationError("please base your interface " \
+ raise InvalidConfigurationError("please base your interface "
"on the base class provided by the fingerd module")
if not isinstance(formatter, _FingerFormatter):
- raise InvalidConfigurationError("please base your formatter " \
+ raise InvalidConfigurationError("please base your formatter "
"on the base class provided by the fingerd module")
if not isinstance(logger, _FingerLogger):
- raise InvalidConfigurationError("please base your logger " \
+ raise InvalidConfigurationError("please base your logger "
"on the base class provided by the fingerd module")
# Keep the parameters.
diff --git a/fingerd/_util.py b/fingerd/_util.py
index 8454827..b51ed34 100755
--- a/fingerd/_util.py
+++ b/fingerd/_util.py
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
-#******************************************************************************
+#**************************************************************************
# Copyright (C) 2017-2019 Thomas Touhey <thomas@touhey.fr>
-# This file is part of the fingerd Python 3.x module, which is MIT-licensed.
-#******************************************************************************
+# This file is part of the fingerd project, which is MIT-licensed.
+#**************************************************************************
""" This file defines the base classes for what is used by the
finger server, directly or indirectly. """
@@ -232,7 +232,8 @@ class _FingerSessionManager:
""" Add a session. """
if not isinstance(session, FingerSession):
- raise TypeError("can only insert sessions into a session manager")
+ raise TypeError("can only insert sessions into a session "
+ "manager")
if session.name is not None:
try:
next(i for i, x in self.__sessions \
@@ -404,9 +405,10 @@ class FingerFormatter:
res = ''
for user in users:
- res += f"Login name: {user.login[:27]:<27} Name: {user.name}\r\n"
- res += f"Directory: {user.home[:28]:<28} Shell: {user.shell}\r\n"
- res += f"Office: {user.office if user.office else ''}\r\n"
+ res += (""
+ f"Login name: {user.login[:27]:<27} Name: {user.name}\r\n"
+ f"Directory: {user.home[:28]:<28} Shell: {user.shell}\r\n"
+ f"Office: {user.office if user.office else ''}\r\n")
if user.sessions:
# List current sessions.
diff --git a/fingerd/control/__init__.py b/fingerd/control/__init__.py
index 83bd37c..ee2a493 100755
--- a/fingerd/control/__init__.py
+++ b/fingerd/control/__init__.py
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
-#******************************************************************************
+#**************************************************************************
# Copyright (C) 2017-2019 Thomas Touhey <thomas@touhey.fr>
-# This file is part of the fingerd Python 3.x module, which is MIT-licensed.
-#******************************************************************************
+# This file is part of the fingerd project, which is MIT-licensed.
+#**************************************************************************
""" The `fingerd.control` submodule is a module for adding actions to the
fingerd live interface. """
@@ -81,8 +81,8 @@ def run():
ap = _ArgumentParser(prog = 'fingerd-control',
description = 'Control the fingerd daemon live interface.')
- ap.add_argument('-t', '--to', help = 'interface provided by the daemon',
- default = 'ipc:///var/run/fingerd.sock')
+ ap.add_argument('-t', '--to', help = ('interface provided by the '
+ 'daemon'), default = 'ipc:///var/run/fingerd.sock')
usap = ap.add_subparsers(metavar = 'any command', dest = 'command',
required = True)
ssap = usap # until i find out how to have “menus”, sorta…
diff --git a/fingerd/control/__main__.py b/fingerd/control/__main__.py
index 59a113a..df21d37 100755
--- a/fingerd/control/__main__.py
+++ b/fingerd/control/__main__.py
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
-#******************************************************************************
+#**************************************************************************
# Copyright (C) 2017-2019 Thomas Touhey <thomas@touhey.fr>
-# This file is part of the fingerd Python 3.x module, which is MIT-licensed.
-#******************************************************************************
+# This file is part of the fingerd project, which is MIT-licensed.
+#**************************************************************************
""" Main script of the control client module.
Runs the client depending on the configuration content. """
diff --git a/scripts/fingerd b/scripts/fingerd
index 5a6c3f9..7fc65dc 100755
--- a/scripts/fingerd
+++ b/scripts/fingerd
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
-#******************************************************************************
+#**************************************************************************
# Copyright (C) 2017-2019 Thomas Touhey <thomas@touhey.fr>
-# This file is part of the fingerd Python 3.x module, which is MIT-licensed.
-#******************************************************************************
+# This file is part of the fingerd project, which is MIT-licensed.
+#**************************************************************************
""" Run fingerd without calling the `fingerd` module directly. """
from fingerd import run as _run
diff --git a/scripts/fingerd-control b/scripts/fingerd-control
index 39ac2b8..5619132 100755
--- a/scripts/fingerd-control
+++ b/scripts/fingerd-control
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
-#******************************************************************************
+#**************************************************************************
# Copyright (C) 2017-2019 Thomas Touhey <thomas@touhey.fr>
-# This file is part of the fingerd Python 3.x module, which is MIT-licensed.
-#******************************************************************************
+# This file is part of the fingerd project, which is MIT-licensed.
+#**************************************************************************
""" Run the fingerd control client without calling the `fingerd.control`
module directly. """
diff --git a/setup.py b/setup.py
index 4ae4872..b326a98 100755
--- a/setup.py
+++ b/setup.py
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
-#******************************************************************************
+#**************************************************************************
# Copyright (C) 2018-2019 Thomas Touhey <thomas@touhey.fr>
# This file is part of the fingerd project, which is MIT-licensed.
-#******************************************************************************
+#**************************************************************************
""" Setup script for the fingerd Python package. """
from setuptools import setup as _setup