Blob


1 version=pmwiki-2.3.20 ordered=1 urlencoded=1
2 agent=Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
3 author=Posterdati
4 charset=UTF-8
5 csum=
6 ctime=1700843694
7 host=93.45.233.109
8 name=Hunchentoot.Install
9 rev=21
10 targets=
11 text=----%0a%0a!'''Common Lisp on OpenBSD'''%0a%0a!!'''With a simple Hunchentoot example'''%0a%0a|| border=1 width=50%25 class="sortable simpletable"%0a||!Revision||!Description||!Name ||%0a||0.0.1 ||This table ||Angelo Rossi %3cangelo.rossi.homelab@gmail.com>||%0a|| || || ||%0a%0a%0a!!!'''Preface to this Edition'''%0a%0aThis is a lone work by Angelo Rossi %3cangelo.rossi.homelab@gmail.com>%0a%0a!!!'''License Information'''%0a%0a[@%0aCopyright (C) 2023 Angelo Rossi %3cangelo.rossi.homelab@gmail.com>%0a%0a%0aRedistribution and use in source and binary forms, with or without%0amodification, are permitted provided that the following conditions%0aare met:%0a%0a%0a1. Redistributions of source code must retain the above copyright%0a notice, this list of conditions and the following disclaimer.%0a2. Redistributions in binary form must reproduce the above copyright%0a notice, this list of conditions and the following disclaimer in the%0a documentation and/or other materials provided with the distribution.%0a3. Neither the name of the University nor the names of its contributors%0a may be used to endorse or promote products derived from this software%0a without specific prior written permission.%0a%0a%0aTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND%0aANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE%0aIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE%0aARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE%0aFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL%0aDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS%0aOR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)%0aHOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT%0aLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY%0aOUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF%0aSUCH DAMAGE.%0a@]%0a%0a----%0a%0a!'''Introduction'''%0a%0aThis document explain how to install and configure sbcl on OpenBSD system.%0aAssuming you already installed this OS on your machine with basic tools and%0adesktop environment or, at least, you are able to use emacs as text editor.%0aFirst of all OpenBSD is a free 4.4BSD-based Unix-like operating system. It has%0agot these unique features:%0a%0a* portability;%0a* standardization;%0a* correctness;%0a* proactive security;%0a* integrated cryptography.%0a%0aFor all of these you could be interested in run a webserver on it. So let's see%0ahow to achieve that and look at a simple way to program a dynamic webserver%0aapplication which in turn use the Common Lisp language to create html pages on%0athe fly.%0a%0a!!'''Foreword'''%0a%0aWhy Common Lisp? One of the question that arises most of the times speaking%0awith people involved in computer science as professionals or reasearches. Most%0aof them look at Lisp (and Common Lisp as a reflex) not only the language%0adeveloped for AI fifty years ago, but something strange and esotheric,%0asomething not really useful and related to a distant past made of punched cards%0aand gigantic magnetic tape reader the size of a fridge. No one take Lisp as%0athe language of the following innovations:%0a%0a* a regular and most simple syntax among high level programming language;%0a* the first high level language used to program an OS (Genera);%0a* used to program one of the first graphic user interface for an OS;%0a* an advanced macro system to generate Lisp code and extend the language (DSL);%0a* A garbage collector;%0a* derived from the mathematics idea of lambda calculus by Alonzo Church;%0a* a major dialect with a standard: ANSI INCITS 226-1994 (S20018).%0a%0a!!'''Who is this guide for?'''%0a%0aThe purpose of this guide is to let the reader discovers one of the most%0aadvanced and complete language in the history of computer science. The usage%0aof Lisp is quite simple since it is based on very basic ideas about%0aprogramming. Since OpenBSD is a modern UNIX OS with excels in some areas like%0asecurity and correctness, this guide could be of some use to people that want%0ato experimenting and deploy secure applications for everyday usage. A basic%0aknowledge of OpenBSD, shell and Common Lisp will boost the process to build%0aand better understand the concept. For those who don't know Common Lisp we%0asuggest to read those books: [BARSKI2010]_ and [SEIBEL2005]_.%0a%0a!!'''Other resources'''%0a%0aOnline official documentation and info sources from:%0a%0a* FAQ manual `%3chttps://www.openbsd.org/faq/index.html>`_%0a* man pages: `%3chttps://man.openbsd.org>`_%0a* Mailing list `%3chttps://www.openbsd.org/mail.html>`_%0a* #OpenBSD IRC channel on Libera Chat `%3circ.libera.chat>`_%0a* #lisp IRC channel on Libera Chat `%3circ.libera.chat>`_%0a* #lisp IRC channel on IRC Now `%3circ.bsdforall.org>`_%0a%0a!!'''Legally speaking...'''%0a%0aWe referenced to the BSD 3 clauses license for this work and the related code.%0a%0a!'''Getting Started'''%0a%0a!!'''The installation process'''%0a%0aWe refer to a running and functional installation of OpenBSD 7.4 for amd64%0aplatform even if the majority of the ideas can be used on othe platform too%0aas sparc64 and arm64. First of all we open a terminal window: OpenBSD uses%0acsh as standard shell interpreter, int this guide we prefer the bash shell%0aso, as root, we can give the command:%0a%0a%0a[@%0a$ doas pkg_add -v bash%0a@]%0a%0a%0aAfter the installation we can add to the system the Stell Bank Common Lisp%0ainterpreter/compiler - sbcl with:%0a%0a%0a[@%0a$ doas pkg_add -v sbcl%0a@]%0a%0a%0a!!'''Configuration for sbcl'''%0a%0aAs installed, sbcl is already working with its default configuration which are%0aspecified in its \*features\* global variable, for example, let's run sbcl:%0a%0a[@%0a$ sbcl%0a@]%0a%0athe system responds with:%0a%0a[@%0aThis is SBCL 2.3.8.openbsd.sbcl-2.3.8, an implementation of ANSI Common Lisp.%0aMore information about SBCL is available at %3chttp://www.sbcl.org/>.%0aSBCL is free software, provided as is, with absolutely no warranty.%0aIt is mostly in the public domain; some portions are provided under%0aBSD-style licenses. See the CREDITS and COPYING files in the%0adistribution for more information.%0a*%0a@]%0a%0aOr with a very similar message, informing us that the interpreter is ready and%0ait is waiting for a command to be entered at the REPL prompt "*".%0a%0aREPL stands for Read, Eval and Print Loop: a way to interact with a user.%0aAt first the informations entered after the prompt are read, then evaluated%0aby the sbcl interpreter and a result is always printed/returned back to the%0auser. The cycle continues with the interpreter waiting for the user to enter%0ainformations again. At this point we would like to see some configurations/characteristics%0aof this particular version of the interpreter, so we enter:%0a%0a[@%0a* *features*%0a(:ARENA-ALLOCATOR :X86-64 :GENCGC :64-BIT :ANSI-CL :BSD :COMMON-LISP :ELF%0a :IEEE-FLOATING-POINT :LITTLE-ENDIAN :OPENBSD :PACKAGE-LOCAL-NICKNAMES%0a :SB-CORE-COMPRESSION :SB-LDB :SB-PACKAGE-LOCKS :SB-THREAD :SB-UNICODE :SBCL%0a :UNIX)%0a@]%0a%0a!!'''Installing quicklisp'''%0a%0aLet's quit the interpreter and continue installing other software that we will%0ause to make a Common Lisp development environment, the editor. We choose emacs%0awhich is, among other things, programmed largely in Lisp, it has inside it a%0aCommon Lisp interpreter which is used to perform operation on text as well as%0aconfigurations:%0a%0a[@%0a$ doas pkg_add -v emacs%0a@]%0a%0aAt this point the installer can ask us to choose among different version of%0aemacs. Choose the one is best with your desktop environment or, if you like%0ainstall the version with no desktop support at all, you can still use it from%0athe console or terminal with no great difference from the desktop version.%0aAlso emacs has got is own configuration which is accessible with the program%0ainterface or modifying a file in the home directory. We will see how to%0aachieve that in the following paragraph, by now let's install the quicklisp%0acommon lisp library system. This is a completely written in Common Lisp%0apiece of software, which make the user capable of handling projects related%0ato Common Lisp itself, we will use it to let our software use already written%0alibraries. To install quicklisp we have to download the quicklisp installer%0afrom the site [[https://beta.quicklisp.org]]. We use curl to do that, so:%0a%0a[@%0a$ doas pkg_add -v curl%0a@]%0a%0aproceed to retrieve the quicklisp library:%0a%0a[@%0a$ curl -O https://beta.quicklisp.org/quicklisp.lisp%0a@]%0a%0aand the library file signature to check its authenticity:%0a%0a[@%0a$ curl -O https://beta.quicklisp.org/quicklisp.lisp.asc%0a@]%0a%0athen we check the signature of the downloaded file:%0a%0a[@%0a$ gpg --verify quicklisp.lisp.asc quicklisp.lisp%0agpg: Signature made Sat Feb 1 09:25:28 2014 EST using RSA key ID 028B5FF7%0agpg: Good signature from "Quicklisp Release Signing Key "%0a@]%0a%0aThe downloaded file is then usable to install the quicklisp library manager. At%0aThis point we face two main choices: we can install the library manager only%0afor the user or system-wide. We assume for now that the installation is%0alimited to one user, so we can proceed as follows:%0a%0a[@%0a%0a$ sbcl --load quicklisp.lisp%0aThis is SBCL 2.3.8.openbsd.sbcl-2.3.8, an implementation of ANSI Common Lisp.%0aMore information about SBCL is available at %3chttp://www.sbcl.org/>.%0a%0aSBCL is free software, provided as is, with absolutely no warranty.%0aIt is mostly in the public domain; some portions are provided under%0aBSD-style licenses. See the CREDITS and COPYING files in the%0adistribution for more information.%0a%0a==== quicklisp quickstart 2015-01-28 loaded ====%0a%0a To continue with installation, evaluate: (quicklisp-quickstart:install)%0a%0a For installation options, evaluate: (quicklisp-quickstart:help)%0a%0a*%0a@]%0a%0aAt this point we can proceed to install the library:%0a%0a[@%0a* (quicklisp-quickstart:install)%0a...%0a==== quicklisp installed ====%0a%0a To load a system, use: (ql:quickload "system-name")%0a%0a To find systems, use: (ql:system-apropos "term")%0a%0a To load Quicklisp every time you start Lisp, use: (ql:add-to-init-file)%0a%0a For more information, see http://www.quicklisp.org/beta/%0a%0aT%0a*%0a@]%0a%0aTo use the library with the sbcl REPL we must instruct sbcl itself to load a%0aconfiguration batch file called .sbclrc which resides in the user home.%0aQuicklisp can do that for us as stated in the message above, in fact let's%0aissue the form in the REPL:%0a%0a[@%0a* (ql:add-to-init-file)%0aI will append the following lines to #P"/home/user/.sbclrc":%0a%0a;;; The following lines added by ql:add-to-init-file:%0a#-quicklisp%0a(let ((quicklisp-init #P"/home/user/quicklisp/setup.lisp"))%0a (when (probe-file quicklisp-init)%0a (load quicklisp-init)))%0a%0aPress Enter to continue.%0a%0a#P"/home/user/.sbclrc"%0a* (quit)%0a$%0a@]%0a%0aTo return to the shell prompt, we can check that the following code is then%0awritten in the .sbclrc file:%0a%0a[@%0a$ cat ~/.sbclrc%0a;;; The following lines added by ql:add-to-init-file:%0a#-quicklisp%0a(let ((quicklisp-init #P"/home/user/quicklisp/setup.lisp"))%0a (when (probe-file quicklisp-init)%0a (load quicklisp-init)))%0a@]%0a%0a.sbclrc is the file which is read and evaluated from sbcl before entering the%0aREPL, we can place configuration code for sbcl in there. For example we want%0asbcl and quicklisp to include our personal Common Lisp projects repository%0awhich is, for example, in ~/Development/lisp directory. So we add the%0afollowing code at the end of .sbclrc:%0a%0a[@%0a(defun setup-registry (directory-path)%0a (format t "; adding components under ~A to asdf registry~%25" directory-path)%0a (mapc (lambda (asd-pathname)%0a (pushnew (make-pathname :name nil%0a :type nil%0a :version nil%0a :defaults asd-pathname)%0a asdf:*central-registry*%0a :test #'equal))%0a (directory (merge-pathnames #p"**/*.asd" directory-path))))%0a%0a(setup-registry (merge-pathnames #p"Development/lisp/" (user-homedir-pathname)))%0a@]%0a%0aLet's see what happens when we launch sbcl:%0a%0a[@%0a$ sbcl%0aThis is SBCL 2.3.8.openbsd.sbcl-2.3.8, an implementation of ANSI Common Lisp.%0aMore information about SBCL is available at %3chttp://www.sbcl.org/>.%0a%0aSBCL is free software, provided as is, with absolutely no warranty.%0aIt is mostly in the public domain; some portions are provided under%0aBSD-style licenses. See the CREDITS and COPYING files in the%0adistribution for more information.%0a; adding components under /home/angel/Development/lisp/ to asdf registry%0a*%0a@]%0a%0aNow let's check what happened to the \*features\*:%0a%0a[@%0a* *features*%0a(:QUICKLISP :ASDF3.3 :ASDF3.2 :ASDF3.1 :ASDF3 :ASDF2 :ASDF :OS-UNIX%0a :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :ARENA-ALLOCATOR :X86-64 :GENCGC :64-BIT%0a :ANSI-CL :BSD :COMMON-LISP :ELF :IEEE-FLOATING-POINT :LITTLE-ENDIAN :OPENBSD%0a :PACKAGE-LOCAL-NICKNAMES :SB-CORE-COMPRESSION :SB-LDB :SB-PACKAGE-LOCKS%0a :SB-THREAD :SB-UNICODE :SBCL :UNIX)%0a*%0a@]%0a%0a!!'''Configuration for emacs'''%0a%0aQuicklisp library added more features to the basic sbcl behaviour especially%0arelated to ASDF. Now let's configure emacs to allow us to have a REPL inside%0aa window:%0a%0a[@%0a$ sbcl%0a...%0a* (ql:quickload :quicklisp-slime-helper)%0a To load "quicklisp-slime-helper":%0a Load 1 ASDF system:%0a quicklisp-slime-helper%0a; Loading "quicklisp-slime-helper"%0a[package swank-loader]............................%0a[package quicklisp-slime-helper]%0aslime-helper.el installed in "/home/user/quicklisp/slime-helper.el"%0a%0aTo use, add this to your ~/.emacs:%0a%0a (load (expand-file-name "/home/user/quicklisp/slime-helper.el"))%0a ;; Replace "sbcl" with the path to your implementation%0a (setq inferior-lisp-program "sbcl")%0a%0a%0a(:QUICKLISP-SLIME-HELPER)%0a*%0a@]%0a%0aTo add the code showed by the message before we shall open ~/.emacs which is%0ain turn the configuration file for emacs and add the lines:%0a%0a[@%0a(load (expand-file-name "/home/user/quicklisp/slime-helper.el"))%0a;; Replace "sbcl" with the path to your implementation%0a(setq inferior-lisp-program "sbcl")%0a@]%0a%0aonce the .emacs file is edited we can launch emacs and we have the window:%0a%0aAttach:emacs-001.png%0a%0awe start SLIME by pressing the key Alt and x on the keyboard, emacs will let us%0aenter a command:%0a%0aAttach:emacs-002.png%0a%0awe enter the command "slime" at the "M-x" prompt:%0a%0aAttach:emacs-003.png%0a%0aand press the enter key on the keyboard. The SLIME REPL appears:%0a%0aAttach:emacs-004.png%0a%0aLet's see what are the \*features\* now using the SLIME REPL:%0a%0aAttach:emacs-005.png%0a%0aWe can try to load a package "antik", and then:%0a%0a[@%0aCL-USER> (ql:quickload :antik)%0a...%0a(:ANTIK)%0aCL-USER>%0a@]%0a%0aantik provides some useful constants and standard quantities handling in%0ascientific calculations such as:%0a%0a[@%0aCL-USER> antik:+days-per-month+%0a30%0aCL-USER>%0a@]%0a%0a----%0a%0a!'''Hunchentoot basic application'''%0a%0a!!'''Hunchentoot installation'''%0a%0aUsing SLIME the Superior Lisp Interaction Mode for Emacs%0a([[https://slime.common-lisp.dev]]), we enter the form:%0a%0a[@%0aCL-USER> (ql:quickload :hunchentoot)%0aTo load "hunchentoot":%0aLoad 1 ASDF system:%0a hunchentoot%0a; Loading "hunchentoot"%0a.%0a(:HUNCHENTOOT)%0aCL-USER>%0a@]%0a%0aDocumentation for the hunchentoot server is at%0a[[https://edicl.github.io/hunchentoot]]. In this example we used the SSL%0alibrary to deploy an SSL enabled webserver, thus we have to create a self%0asigned certificate to run the server. Following these hints let you create%0awhat needed for the server. First of all let's install the openssl library and%0atools:%0a%0a[@%0a$ doas pkg_add -v openssl%0a@]%0a%0awe choose 1: openssl-3.1.3, after the installation we issue the command%0a%0a[@%0a $ openssl version%0aLibreSSL 3.8.2%0a$%0a@]%0a%0athis means the library is correctly installed and ready to be used to create%0aour certificate and key:%0a%0a[@%0a$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ~/selfsigned.key -out ~/selfsigned.crt%0a........................................................%0a.........................................................................................................................................%0awriting new private key to '/home/angel/selfsigned.key'%0a-----%0aYou are about to be asked to enter information that will be incorporated%0ainto your certificate request.%0aWhat you are about to enter is what is called a Distinguished Name or a DN.%0aThere are quite a few fields but you can leave some blank%0aFor some fields there will be a default value,%0aIf you enter '.', the field will be left blank.%0a-----%0aCountry Name (2 letter code) []:IT%0aState or Province Name (full name) []:Italy%0aLocality Name (eg, city) []:Rome%0aOrganization Name (eg, company) []:Antani S.r.l.%0aOrganizational Unit Name (eg, section) []:R&D%0aCommon Name (eg, fully qualified host name) []:antani.it%0aEmail Address []:antani@antani.it%0a$%0a@]%0a%0aLet's create .pem files to use in clients transactions with the server:%0a%0a[@%0a$ openssl x509 -in ~/selfsigned.crt -out ~/selfsigned-crt.pem -outform PEM%0a$ openssl rsa -in selfsigned.key -text > selfsigned-key.pem%0awriting RSA key%0a$%0a@]%0a%0aso we finally have:%0a%0a[@%0a$ ls ~/selfsigned*%0a/home/user/selfsigned-crt.pem /home/user/selfsigned-key.pem /home/user/selfsigned.crt /home/user/selfsigned.key%0a$%0a@]%0a%0awe can directly use the .pem files to run our test SSL-based webserver. Those%0afiles have to be moved inside our Common Lisp project directory, which at this%0atime is non-existent.%0a%0a!!'''Project creation and configuration'''%0a%0aTo create an empty project skeleton we have to use%0aanother useful quicklisp library: quickproject, so let's return to the SLIME%0aREPL prompt on emacs and enter the form.\\%0a%0aA form is something enclosed in "(" and ")" pair, it is the way the Common%0aLisp interpreter understand the commands and data entered via the REPL.%0aIn the same way, Common Lisp programs are composed by forms which may%0acontains other forms as well. There are other objects that can be entered%0ain the REPL and evaluated, they are: numbers, symbols, keywords, strings,%0acharacters, t and nil. Those objects it said that evaluate to themselves.%0a%0a[@%0aCL-USER> (ql:quickload :quickproject)%0aTo load "quickproject":%0aLoad 1 ASDF system:%0a quickproject%0a; Loading "quickproject"%0a[package html-template]...........................%0a[package quickproject].%0a(:QUICKPROJECT)%0aCL-USER>%0a@]%0a%0aWe are ready to create a skeleton project and hack it to perform the required%0atask. Just enter:%0a%0a[@%0aCL-USER> (quickproject:make-project #p"/home/user/Development/lisp/test-hunchentoot"%0a :depends-on '(#:cl-fad%0a #:cl-who%0a #:cl+ssl%0a #:ironclad%0a #:lass%0a #:parenscript%0a #:hunchentoot%0a #:bordeaux-threads%0a #:simple-date-time)%0a :author "antani %3cantani@antani.it>"%0a :license "BSD")%0aWARNING:%0a Coercing #p"/home/user/Development/lisp/test-hunchentoot" to directory%0a"test-hunchentoot"%0aCL-USER>%0a@]%0a%0aThe project is then created following the path%0a/home/user/Development/lisp/test-hunchentoot. We can check that issuing from%0athe shell:%0a%0a[@%0a$ ls ~/Development/lisp%0atest-hunchentoot%0a@]%0a%0aand then:%0a%0a[@%0a$ ls ~/Development/lisp/test-hunchentoot%0aREADME.md package.lisp test-hunchentoot.asd test-hunchentoot.lisp%0a$%0a@]%0a%0aFor a small project we can leave this layout as it is, but since we do not know%0athe future development of the project, one can follow this example or feel free%0ato reshape the project layout as it fits the purpose:%0a%0a[@%0a$ cd ~/Development/lisp/test-hunchentoot%0a$ mkdir sources scripts docs%0a$ mv *.lisp sources/%0a$ ls%0aREADME.md docs scripts sources test-hunchentoot.asd%0a$%0a@]%0a%0aSo we leave .lisp files inside the sources/ directory and the system files on%0athe project root directory. Now let's see what is inside the files created%0aby quickproject, just pick test-hunchentoot.asd using emacs menu "File", then%0a"Open File..." and choose the correct file navigating the user home directory:%0a%0a[@%0a;;;; test-hunchentoot.asd%0a%0a(asdf:defsystem #:testina-hunchentoot%0a :description "Describe test-hunchentoot here"%0a :author "antani %3cantani@antani.it>"%0a :license "BSD"%0a :version "0.0.1"%0a :serial t%0a :depends-on (#:cl-fad #:cl-who #:cl+ssl #:ironclad #:lass #:parenscript #:hunchentoot #:bordeaux-threads #:simple-date-time)%0a :components ((:file "package")%0a (:file "testina-hunchentoot")))%0a@]%0a%0aWe created a PEM certificate and a key, we can move them inside the project directory with:%0a%0a[@%0a$ mv ~/selfsigned-crt.pem ~/Development/lisp/test-hunchentoot/scripts/%0a$ mv ~/selfsigned-key.pem ~/Development/lisp/test-hunchentoot/scripts/%0a$%0a@]%0a%0aSo we can reference them starting from the hunchentoot server document root%0adirectory. Before entering the application programming phase, we want to%0aadd legal notices (license) to the project files. We follow this convention:%0aevery file containing code related to system definitions and packaging will be%0amarked with a license text, here an example test-hunchentoot.asd file in which%0athe test-hunchentoot system is defined:%0a%0a[@%0a;;;;***************************************************************************%0a;;;; test-hunchentoot.asd%0a;;;;%0a;;;; Copyright 2023 Antani %3cantani@antani.it>%0a;;;;%0a;;;; Redistribution and use in source and binary forms, with or without%0a;;;; modification, are permitted provided that the following conditions are met:%0a;;;;%0a;;;; 1. Redistributions of source code must retain the above copyright notice,%0a;;;; this list of conditions and the following disclaimer.%0a;;;;%0a;;;; 2. Redistributions in binary form must reproduce the above copyright%0a;;;; notice, this list of conditions and the following disclaimer in the%0a;;;; documentation and/or other materials provided with the distribution.%0a;;;;%0a;;;; 3. Neither the name of the copyright holder nor the names of its%0a;;;; contributors may be used to endorse or promote products derived from%0a;;;; this software without specific prior written permission.%0a;;;;%0a;;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND%0a;;;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED%0a;;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE%0a;;;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE%0a;;;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL%0a;;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR%0a;;;; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER%0a;;;; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,%0a;;;; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE%0a;;;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.%0a;;;;***************************************************************************%0a%0a(asdf:defsystem #:test-hunchentoot%0a :description "Test hunchentoot server (SSL version)."%0a :author "Antani %3cantani@antani.it>"%0a :license "BSD"%0a :depends-on (#:cl-fad%0a #:cl-who%0a #:cl+ssl%0a #:ironclad%0a #:lass%0a #:parenscript%0a #:hunchentoot%0a #:bordeaux-threads%0a #:simple-date-time)%0a :serial t%0a :components ((:file "sources/package")%0a (:file "sources/parameters")%0a (:file "sources/system")%0a (:file "sources/test-hunchentoot")))%0a%0a;; End of file test-hunchentoot.asd%0a@]%0a%0aTo automate the process of inserting this license text, we can create a text%0afile and insert it in the source file we want to modify, for example let's call%0ait LICENSE:%0a%0a[@%0a;;;; Copyright 2023 Antani %3cantani@antani.it>%0a;;;;%0a;;;; Redistribution and use in source and binary forms, with or without%0a;;;; modification, are permitted provided that the following conditions are met:%0a;;;;%0a;;;; 1. Redistributions of source code must retain the above copyright notice,%0a;;;; this list of conditions and the following disclaimer.%0a;;;;%0a;;;; 2. Redistributions in binary form must reproduce the above copyright%0a;;;; notice, this list of conditions and the following disclaimer in the%0a;;;; documentation and/or other materials provided with the distribution.%0a;;;;%0a;;;; 3. Neither the name of the copyright holder nor the names of its%0a;;;; contributors may be used to endorse or promote products derived from%0a;;;; this software without specific prior written permission.%0a;;;;%0a;;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND%0a;;;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED%0a;;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE%0a;;;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE%0a;;;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL%0a;;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR%0a;;;; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER%0a;;;; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,%0a;;;; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE%0a;;;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.%0a;;;;***************************************************************************%0a@]%0a%0aso a source code file related to packaging and system definitions will have%0athis shape:%0a%0a* a comment containing emacs configurations and mode for the file;%0a* a separator;%0a* the name of the file itself;%0a* a separator;%0a* the licensing information;%0a* a separator;%0a* source code;%0a* an end of file comment.%0a%0aOther source code files, instead will have this shape:%0a%0a* a comment containing emacs configurations and mode for the file;%0a* a separator;%0a* the file name;%0a* a description of the file contents;%0a* a separator;%0a* source code;%0a* an end of file comment.%0a%0aWe remind you that in Common Lisp comments always begin with ";" until the end%0aof the line. There are some conventions on the use of ";" itself. The%0afollowing rules are taken from "Google Common Lisp Style Guide" at%0a[[https://google.github.io/styleguide/lispguide.xml]]%0a%0a* File headers and important comments that apply to large sections of code in a source file should begin with four semicolons.%0a* You should use three semicolons to begin comments that apply to just one top-level form or small group of top-level forms.%0a* Inside a top-level form, you should use two semicolons to begin a comment if it appears between lines.%0a* You should use one semicolon if it is a parenthetical remark and occurs at the end of a line. You should use spaces to separate the comment from the code it refers to so the comment stands out. You should try to vertically align consecutive related end-of-line comments.%0a%0aThe complete project would appear as follows:%0a%0a[@%0a$ tree%0a.%0a|-- LICENCE%0a|-- README%0a|-- scripts%0a| |-- run-webserver.sh%0a| |-- selfsigned-crt.pem%0a| `-- selfsigned-key.pem%0a|-- sources%0a| |-- package.lisp%0a| |-- parameters.lisp%0a| |-- system.lisp%0a| `-- test-hunchentoot.lisp%0a`-- test-hunchentoot.asd%0a%0a2 directories, 10 files%0a$%0a@]%0a%0aFile are listed as follows. For the package.lisp file in sources/:%0a%0a[@%0a;;;; -*- mode: common-lisp-mode; electric-indent-mode: t; coding: utf-8 -*-%0a;;;;***************************************************************************%0a;;;; package.lisp%0a;;;;***************************************************************************%0a;;;; Copyright 2023 Antani %3cantani@antani.it>%0a;;;;%0a;;;; Redistribution and use in source and binary forms, with or without%0a;;;; modification, are permitted provided that the following conditions are met:%0a;;;;%0a;;;; 1. Redistributions of source code must retain the above copyright notice,%0a;;;; this list of conditions and the following disclaimer.%0a;;;;%0a;;;; 2. Redistributions in binary form must reproduce the above copyright%0a;;;; notice, this list of conditions and the following disclaimer in the%0a;;;; documentation and/or other materials provided with the distribution.%0a;;;;%0a;;;; 3. Neither the name of the copyright holder nor the names of its%0a;;;; contributors may be used to endorse or promote products derived from%0a;;;; this software without specific prior written permission.%0a;;;;%0a;;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND%0a;;;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED%0a;;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE%0a;;;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE%0a;;;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL%0a;;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR%0a;;;; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER%0a;;;; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,%0a;;;; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE%0a;;;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.%0a;;;;***************************************************************************%0a%0a(defpackage #:test-hunchentoot%0a (:use #:cl)%0a (:export #:start-web-server%0a #:stop-web-server))%0a%0a;;;; End of file package.lisp%0a@]%0a%0aFor the parameters.lisp file in sources/:%0a%0a[@%0a;;;; -*- mode: common-lisp-mode; electric-indent-mode: t; coding: utf-8 -*-%0a;;;;***************************************************************************%0a;;;; parameters.lisp%0a;;;;***************************************************************************%0a;;;; Parameters and variables definitions for the project test-hunchentoot.%0a;;;;***************************************************************************%0a%0a(in-package #:test-hunchentoot)%0a%0a;;;; Parameters.%0a(defparameter *ssl-acceptor* nil)%0a(defparameter *default-document-root-directory-pathname* (cl-fad:merge-pathnames-as-directory (user-homedir-pathname) #p"Development/lisp/test-hunchentoot/"))%0a(defparameter *default-ssl-private-key-file-pathname* (cl-fad:merge-pathnames-as-file (user-homedir-pathname) #p"Development/lisp/test-hunchentoot/scripts/selfsigned-key.pem"))%0a(defparameter *default-ssl-certificate-file-pathname* (cl-fad:merge-pathnames-as-file (user-homedir-pathname) #p"Development/lisp/test-hunchentoot/scripts/selfsigned-crt.pem"))%0a(defparameter *default-port* 4242)%0a(defparameter *default-ssl-port* 9443)%0a(defparameter *port* 4242)%0a(defparameter *ssl-port* 9443)%0a(defparameter *default-start-page-reload-timeout* 0)%0a(defparameter *default-info-email* "antani@antani.it")%0a(defparameter *fruits* '(apple pear banana orange avocado pineapple peach plum))%0a%0a;;;; End of file parameters.lisp%0a@]%0a%0aFor the system.lisp file in sources/:%0a%0a[@%0a;;;; -*- mode: common-lisp-mode; electric-indent-mode: t; coding: utf-8 -*-%0a;;;;***************************************************************************%0a;;;; system.lisp%0a;;;;***************************************************************************%0a;;;; Provide data structures and classes definitions for the project%0a;;;; test-hunchentoot.%0a;;;;***************************************************************************%0a%0a(in-package #:test-hunchentoot)%0a%0a;; System class.%0a(defclass system-class ()%0a ((acceptor :initarg :acceptor :accessor acceptor :initform nil)%0a (ssl-acceptor :initarg :ssl-acceptor :accessor ssl-acceptor :initform nil)%0a (lock-object :initarg :lock-object :accessor lock-object :initform nil)%0a (condition-object :initarg :condition-object :accessor condition-object :initform nil)))%0a%0a;; functions.%0a%0a(defun make-system (&rest parameters &key (acceptor nil acceptor-p) (ssl-acceptor nil ssl-acceptor-p) (lock-object nil lock-object-p) (condition-object nil condition-object-p))%0a "Create an instance of the system-class."%0a (declare (ignorable parameters%0a acceptor%0a ssl-acceptor%0a lock-object%0a condition-object))%0a (make-instance 'system-class%0a :acceptor acceptor%0a :ssl-acceptor ssl-acceptor%0a :lock-object lock-object%0a :condition-object condition-object))%0a%0a;;;; End of file system.lisp%0a@]%0a%0aFor the test-hunchentoot.lisp file in sources/:%0a%0a[@%0a;;;; -*- mode: common-lisp-mode; electric-indent-mode: t; coding: utf-8 -*-%0a;;;;***************************************************************************%0a;;;; test-hunchentoot.lisp%0a;;;;***************************************************************************%0a;;;; This file contains all the functions for the test-hunchentoot project.%0a;;;;***************************************************************************%0a;;;;%0a%0a(in-package #:test-hunchentoot)%0a%0a;; "test-hunchentoot" goes here. Hacks and glory await!%0a;; Initial setup for javascript environment%0a(eval-when (:compile-toplevel :execute)%0a (setq cl-who:*attribute-quote-char* #\"%0a ps:*js-string-delimiter* #\"))%0a%0a;; Methods.%0a(defmethod hunchentoot:acceptor-dispatch-request ((vhost system-class) request)%0a (mapc (lambda (dispatcher)%0a (let ((handler (funcall dispatcher request)))%0a (when handler%0a (return-from hunchentoot:acceptor-dispatch-request (funcall handler)))))%0a (dispatch-table vhost))%0a (call-next-method))%0a%0a(defmethod start-web-server ((object system-class) &rest parameters &key %0a (document-root-directory-pathname *default-document-root-directory-pathname* document-root-directory-pathname-p)%0a (ssl-private-key-file-pathname *default-ssl-private-key-file-pathname* ssl-private-key-file-pathname-p)%0a (ssl-certificate-file-pathname *default-ssl-certificate-file-pathname* ssl-certificate-file-pathname-p)%0a (address "localhost" address-p)%0a (port *default-port* port-p)%0a (ssl-port *default-ssl-port* ssl-port-p)%0a (page-reload-timeout *default-start-page-reload-timeout* page-reload-timeout-p)%0a (verbose nil))%0a "Configure and start the hunchentoot webserver."%0a (declare (ignorable parameters%0a document-root-directory-pathname%0a ssl-private-key-file-pathname%0a ssl-certificate-file-pathname%0a address%0a port%0a ssl-port%0a page-reload-timeout%0a verbose))%0a (when document-root-directory-pathname-p%0a (check-type document-root-directory-pathname pathname)%0a (assert (cl-fad:directory-exists-p document-root-directory-pathname)))%0a (when ssl-private-key-file-pathname-p%0a (check-type ssl-private-key-file-pathname pathname)%0a (assert (cl-fad:file-exists-p ssl-private-key-file-pathname)))%0a (when ssl-certificate-file-pathname-p%0a (check-type ssl-certificate-file-pathname pathname)%0a (assert (cl-fad:file-exists-p ssl-certificate-file-pathname)))%0a (when address-p%0a (check-type address string))%0a (when port-p%0a (check-type port (unsigned-byte 16)))%0a (when ssl-port-p%0a (check-type ssl-port (unsigned-byte 16)))%0a (when (and port-p ssl-port-p)%0a (assert (/= port ssl-port)))%0a (when page-reload-timeout-p%0a (check-type page-reload-timeout (unsigned-byte 16)))%0a ;;%0a (setq *random-state* (make-random-state t))%0a (unwind-protect%0a (let* ((hunchentoot:*log-lisp-errors-p* t)%0a (hunchentoot:*log-lisp-warnings-p* t)%0a (hunchentoot:*catch-errors-p* nil)%0a (stdin (sb-sys:make-fd-stream 0%0a :input t%0a :buffering :full%0a :element-type '(unsigned-byte 8)))%0a (cl+ssl:make-ssl-client-stream (cl+ssl:stream-fd stdin)))%0a (setf (lock-object object) (bt:make-lock (symbol-name (gensym "webserver-lock-"))))%0a (setf (condition-object object) (bt:make-condition-variable :name (symbol-name (gensym "webserver-condition-"))))%0a ;; Server setup and start%0a (setf (ssl-acceptor object) (make-instance 'hunchentoot:easy-ssl-acceptor%0a :name 'ssl-acceptor%0a :ssl-privatekey-file ssl-private-key-file-pathname%0a :ssl-certificate-file ssl-certificate-file-pathname%0a :address address%0a :port ssl-port%0a :document-root document-root-directory-pathname))%0a (hunchentoot:start (ssl-acceptor object))%0a (setq *ssl-acceptor* (ssl-acceptor object))%0a (when verbose%0a (format *standard-output*%0a "~%25;; Starting SSL Web Server on port ~a.~%25~%25" ssl-port)%0a (format *standard-output*%0a ";; Certificate pathname ~s.~%25" ssl-certificate-file-pathname)%0a (format *standard-output*%0a ";; Private key pathname ~s.~%25~%25" ssl-private-key-file-pathname)%0a (finish-output *standard-output*))%0a (setq hunchentoot:*dispatch-table* (list 'hunchentoot:dispatch-easy-handlers))%0a (loop%0a named wait-loop%0a do%0a (handler-case%0a (progn%0a (bt:with-lock-held ((lock-object object))%0a (bt:condition-wait (condition-object object)%0a (lock-object object)))%0a (return-from wait-loop))%0a (hunchentoot:hunchentoot-error (he)%0a (format *standard-output* "~s~%25" he)%0a (finish-output *standard-output*))%0a (error (e)%0a (format *standard-output* "~s~%25" e)%0a (finish-output *standard-output*)%0a (return-from wait-loop))%0a (warning (w)%0a (format *standard-output* "~s~%25" w)%0a (finish-output *standard-output*)))))%0a ;; unwind-protect cleanup form.%0a (progn%0a (when verbose%0a (format *standard-output* ";; Shutting down webserver.~%25")%0a (finish-output *standard-output*))%0a (stop-web-server object :verbose t))))%0a%0a(defmethod stop-web-server ((object system-class) &rest parameters &key (verbose nil))%0a "Stop the hunchentoot webserver."%0a (declare (ignorable parameters verbose))%0a (when (ssl-acceptor object)%0a (hunchentoot:stop (ssl-acceptor object))%0a (setq *ssl-acceptor* nil)%0a (when verbose%0a (format *standard-output*%0a "~%25;; Stopping SSL Web Server.~%25~%25")%0a (finish-output *standard-output*)))%0a (bt:condition-notify (condition-object object)))%0a%0a;; Functions.%0a(defun remove-nth (index object)%0a "remove the nth element from the list."%0a (remove-if (constantly t)%0a object%0a :start index%0a :count 1))%0a%0a;; Hunchentoot html stuffs.%0a(hunchentoot:define-easy-handler (main-page :uri "/") ()%0a "The main page handler for http request."%0a (hunchentoot:redirect "/index"))%0a%0a(hunchentoot:define-easy-handler (index-page :uri "/index") ()%0a "The /index page handler for http request."%0a (let ((temporary-fruits *fruits*)%0a (i nil))%0a (cl-who:with-html-output-to-string (s)%0a (cl-who:htm%0a (:html%0a (:h1 "This is an example of dynamic list:")%0a (:br)%0a (:ul%0a (loop%0a while (> (length temporary-fruits) 0)%0a do%0a (setq i (random (length temporary-fruits)))%0a (cl-who:htm%0a (:li (cl-who:str (nth i temporary-fruits))))%0a (setq temporary-fruits (remove-nth i temporary-fruits)))))))))%0a%0a;; Start at quickload.%0a(start-web-server (make-system)%0a :ssl-port *default-ssl-port*%0a :verbose t)%0a%0a;;;; End of file test-hunchentoot.lisp%0a@]%0a%0a%0aThe file run-webserver.sh is a bash script to launch the webserver without use %0aemacs SLIME or sbcl from the console, for clarity it is listed below:%0a%0a[@%0a#!/bin/bash%0a%0ainterpreter="ecl"%0aecl_program=`which ecl`%0asbcl_program=`which sbcl`%0alisp_form="(ql:quickload :test-hunchentoot)"%0a%0acase $interpreter in%0a "ecl") if [ -x $ecl_program ]; then%0a nohup $ecl_program --eval "$lisp_form" > output.txt 2>&1 &%0a fi%0a ;;%0a "sbcl") if [ -x $sbcl_program ]; then%0a nohup $sbcl_program --eval "$lisp_form" > output.txt 2>&1 &%0a fi%0a ;;%0aesac%0a@]%0a%0aTo test our SSL server we can connect to it using a browser on a machine connected%0aon the same LAN. For example as in the image below:%0a%0aAttach:firefox-001.png
12 time=1700855441
13 author:1700855441=Posterdati
14 diff:1700855441:1700855370:=1066c1066%0a%3c lisp_form="(ql:quickload :test-hunchentoot)"%0a---%0a> lisp_form="(ql:quickload :ssl-smt-webserver)"%0a
15 host:1700855441=93.45.233.109
16 author:1700855370=Posterdati
17 diff:1700855370:1700855112:=1054,1077d1053%0a%3c @]%0a%3c %0a%3c %0a%3c The file run-webserver.sh is a bash script to launch the webserver without use %0a%3c emacs SLIME or sbcl from the console, for clarity it is listed below:%0a%3c %0a%3c [@%0a%3c #!/bin/bash%0a%3c %0a%3c interpreter="ecl"%0a%3c ecl_program=`which ecl`%0a%3c sbcl_program=`which sbcl`%0a%3c lisp_form="(ql:quickload :ssl-smt-webserver)"%0a%3c %0a%3c case $interpreter in%0a%3c "ecl") if [ -x $ecl_program ]; then%0a%3c nohup $ecl_program --eval "$lisp_form" > output.txt 2>&1 &%0a%3c fi%0a%3c ;;%0a%3c "sbcl") if [ -x $sbcl_program ]; then%0a%3c nohup $sbcl_program --eval "$lisp_form" > output.txt 2>&1 &%0a%3c fi%0a%3c ;;%0a%3c esac%0a
18 host:1700855370=93.45.233.109
19 author:1700855112=Posterdati
20 diff:1700855112:1700855037:=20,48c20,48%0a%3c Copyright (C) 2023 Angelo Rossi %3cangelo.rossi.homelab@gmail.com>%0a%3c %0a%3c %0a%3c Redistribution and use in source and binary forms, with or without%0a%3c modification, are permitted provided that the following conditions%0a%3c are met:%0a%3c %0a%3c %0a%3c 1. Redistributions of source code must retain the above copyright%0a%3c notice, this list of conditions and the following disclaimer.%0a%3c 2. Redistributions in binary form must reproduce the above copyright%0a%3c notice, this list of conditions and the following disclaimer in the%0a%3c documentation and/or other materials provided with the distribution.%0a%3c 3. Neither the name of the University nor the names of its contributors%0a%3c may be used to endorse or promote products derived from this software%0a%3c without specific prior written permission.%0a%3c %0a%3c %0a%3c THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND%0a%3c ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE%0a%3c IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE%0a%3c ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE%0a%3c FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL%0a%3c DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS%0a%3c OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)%0a%3c HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT%0a%3c LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY%0a%3c OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF%0a%3c SUCH DAMAGE.%0a---%0a> Copyright (C) 2023 Angelo Rossi %3cangelo.rossi.homelab@gmail.com>\\%0a> %0a> %0a> Redistribution and use in source and binary forms, with or without\\%0a> modification, are permitted provided that the following conditions\\%0a> are met:\\%0a> %0a> %0a> 1. Redistributions of source code must retain the above copyright\\%0a> notice, this list of conditions and the following disclaimer.\\%0a> 2. Redistributions in binary form must reproduce the above copyright\\%0a> notice, this list of conditions and the following disclaimer in the\\%0a> documentation and/or other materials provided with the distribution.\\%0a> 3. Neither the name of the University nor the names of its contributors\\%0a> may be used to endorse or promote products derived from this software\\%0a> without specific prior written permission.\\%0a> %0a> %0a> THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\\%0a> ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\\%0a> IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\\%0a> ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\\%0a> FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\\%0a> DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\\%0a> OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\\%0a> HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\\%0a> LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\\%0a> OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\\%0a> SUCH DAMAGE.\\%0a
21 host:1700855112=93.45.233.109
22 author:1700855037=Posterdati
23 diff:1700855037:1700854665:=19d18%0a%3c [@%0a49d47%0a%3c @]%0a
24 host:1700855037=93.45.233.109
25 author:1700854665=Posterdati
26 diff:1700854665:1700854589:=1,2d0%0a%3c ----%0a%3c %0a
27 host:1700854665=93.45.233.109
28 author:1700854589=Posterdati
29 diff:1700854589:1700854505:=47,48d46%0a%3c ----%0a%3c %0a428,429d425%0a%3c %0a%3c ----%0a
30 host:1700854589=93.45.233.109
31 author:1700854505=Posterdati
32 diff:1700854505:1700854464:=
33 host:1700854505=93.45.233.109
34 author:1700854464=Posterdati
35 diff:1700854464:1700849830:=1046,1051c1046%0a%3c @]%0a%3c %0a%3c To test our SSL server we can connect to it using a browser on a machine connected%0a%3c on the same LAN. For example as in the image below:%0a%3c %0a%3c Attach:firefox-001.png%0a\ No newline at end of file%0a---%0a> @]%0a\ No newline at end of file%0a
36 host:1700854464=93.45.233.109
37 author:1700849830=Posterdati
38 csum:1700849830=OpenBSD, Common Lisp, Hunchentoot, emacs, SLIME, sbcl
39 diff:1700849830:1700849780:=
40 host:1700849830=93.45.233.109
41 author:1700849780=Posterdati
42 diff:1700849780:1700849749:=
43 host:1700849780=93.45.233.109
44 author:1700849749=Posterdati
45 diff:1700849749:1700849198:=390,391c390,393%0a%3c Attach:emacs-001.png%0a%3c %0a---%0a> %0a> .. image:: ./images/emacs-001.png%0a> %0a> %0a395,396c397,400%0a%3c Attach:emacs-002.png%0a%3c %0a---%0a> %0a> .. image:: ./images/emacs-002.png%0a> %0a> %0a399,400c403,406%0a%3c Attach:emacs-003.png%0a%3c %0a---%0a> %0a> .. image:: ./images/emacs-003.png%0a> %0a> %0a403,404c409,412%0a%3c Attach:emacs-004.png%0a%3c %0a---%0a> %0a> .. image:: ./images/emacs-004.png%0a> %0a> %0a407,408c415,418%0a%3c Attach:emacs-005.png%0a%3c %0a---%0a> %0a> .. image:: ./images/emacs-005.png%0a> %0a> %0a886d895%0a%3c ;; "test-hunchentoot" goes here. Hacks and glory await!%0a891c900%0a%3c %0a---%0a> ;; "test-hunchentoot" goes here. Hacks and glory await!%0a900c909%0a%3c %0a---%0a> ;;%0a
46 host:1700849749=93.45.233.109
47 author:1700849198=Posterdati
48 diff:1700849198:1700847574:=437,1055d436%0a%3c !'''Hunchentoot basic application'''%0a%3c %0a%3c !!'''Hunchentoot installation'''%0a%3c %0a%3c Using SLIME the Superior Lisp Interaction Mode for Emacs%0a%3c ([[https://slime.common-lisp.dev]]), we enter the form:%0a%3c %0a%3c [@%0a%3c CL-USER> (ql:quickload :hunchentoot)%0a%3c To load "hunchentoot":%0a%3c Load 1 ASDF system:%0a%3c hunchentoot%0a%3c ; Loading "hunchentoot"%0a%3c .%0a%3c (:HUNCHENTOOT)%0a%3c CL-USER>%0a%3c @]%0a%3c %0a%3c Documentation for the hunchentoot server is at%0a%3c [[https://edicl.github.io/hunchentoot]]. In this example we used the SSL%0a%3c library to deploy an SSL enabled webserver, thus we have to create a self%0a%3c signed certificate to run the server. Following these hints let you create%0a%3c what needed for the server. First of all let's install the openssl library and%0a%3c tools:%0a%3c %0a%3c [@%0a%3c $ doas pkg_add -v openssl%0a%3c @]%0a%3c %0a%3c we choose 1: openssl-3.1.3, after the installation we issue the command%0a%3c %0a%3c [@%0a%3c $ openssl version%0a%3c LibreSSL 3.8.2%0a%3c $%0a%3c @]%0a%3c %0a%3c this means the library is correctly installed and ready to be used to create%0a%3c our certificate and key:%0a%3c %0a%3c [@%0a%3c $ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ~/selfsigned.key -out ~/selfsigned.crt%0a%3c ........................................................%0a%3c .........................................................................................................................................%0a%3c writing new private key to '/home/angel/selfsigned.key'%0a%3c -----%0a%3c You are about to be asked to enter information that will be incorporated%0a%3c into your certificate request.%0a%3c What you are about to enter is what is called a Distinguished Name or a DN.%0a%3c There are quite a few fields but you can leave some blank%0a%3c For some fields there will be a default value,%0a%3c If you enter '.', the field will be left blank.%0a%3c -----%0a%3c Country Name (2 letter code) []:IT%0a%3c State or Province Name (full name) []:Italy%0a%3c Locality Name (eg, city) []:Rome%0a%3c Organization Name (eg, company) []:Antani S.r.l.%0a%3c Organizational Unit Name (eg, section) []:R&D%0a%3c Common Name (eg, fully qualified host name) []:antani.it%0a%3c Email Address []:antani@antani.it%0a%3c $%0a%3c @]%0a%3c %0a%3c Let's create .pem files to use in clients transactions with the server:%0a%3c %0a%3c [@%0a%3c $ openssl x509 -in ~/selfsigned.crt -out ~/selfsigned-crt.pem -outform PEM%0a%3c $ openssl rsa -in selfsigned.key -text > selfsigned-key.pem%0a%3c writing RSA key%0a%3c $%0a%3c @]%0a%3c %0a%3c so we finally have:%0a%3c %0a%3c [@%0a%3c $ ls ~/selfsigned*%0a%3c /home/user/selfsigned-crt.pem /home/user/selfsigned-key.pem /home/user/selfsigned.crt /home/user/selfsigned.key%0a%3c $%0a%3c @]%0a%3c %0a%3c we can directly use the .pem files to run our test SSL-based webserver. Those%0a%3c files have to be moved inside our Common Lisp project directory, which at this%0a%3c time is non-existent.%0a%3c %0a%3c !!'''Project creation and configuration'''%0a%3c %0a%3c To create an empty project skeleton we have to use%0a%3c another useful quicklisp library: quickproject, so let's return to the SLIME%0a%3c REPL prompt on emacs and enter the form.\\%0a%3c %0a%3c A form is something enclosed in "(" and ")" pair, it is the way the Common%0a%3c Lisp interpreter understand the commands and data entered via the REPL.%0a%3c In the same way, Common Lisp programs are composed by forms which may%0a%3c contains other forms as well. There are other objects that can be entered%0a%3c in the REPL and evaluated, they are: numbers, symbols, keywords, strings,%0a%3c characters, t and nil. Those objects it said that evaluate to themselves.%0a%3c %0a%3c [@%0a%3c CL-USER> (ql:quickload :quickproject)%0a%3c To load "quickproject":%0a%3c Load 1 ASDF system:%0a%3c quickproject%0a%3c ; Loading "quickproject"%0a%3c [package html-template]...........................%0a%3c [package quickproject].%0a%3c (:QUICKPROJECT)%0a%3c CL-USER>%0a%3c @]%0a%3c %0a%3c We are ready to create a skeleton project and hack it to perform the required%0a%3c task. Just enter:%0a%3c %0a%3c [@%0a%3c CL-USER> (quickproject:make-project #p"/home/user/Development/lisp/test-hunchentoot"%0a%3c :depends-on '(#:cl-fad%0a%3c #:cl-who%0a%3c #:cl+ssl%0a%3c #:ironclad%0a%3c #:lass%0a%3c #:parenscript%0a%3c #:hunchentoot%0a%3c #:bordeaux-threads%0a%3c #:simple-date-time)%0a%3c :author "antani %3cantani@antani.it>"%0a%3c :license "BSD")%0a%3c WARNING:%0a%3c Coercing #p"/home/user/Development/lisp/test-hunchentoot" to directory%0a%3c "test-hunchentoot"%0a%3c CL-USER>%0a%3c @]%0a%3c %0a%3c The project is then created following the path%0a%3c /home/user/Development/lisp/test-hunchentoot. We can check that issuing from%0a%3c the shell:%0a%3c %0a%3c [@%0a%3c $ ls ~/Development/lisp%0a%3c test-hunchentoot%0a%3c @]%0a%3c %0a%3c and then:%0a%3c %0a%3c [@%0a%3c $ ls ~/Development/lisp/test-hunchentoot%0a%3c README.md package.lisp test-hunchentoot.asd test-hunchentoot.lisp%0a%3c $%0a%3c @]%0a%3c %0a%3c For a small project we can leave this layout as it is, but since we do not know%0a%3c the future development of the project, one can follow this example or feel free%0a%3c to reshape the project layout as it fits the purpose:%0a%3c %0a%3c [@%0a%3c $ cd ~/Development/lisp/test-hunchentoot%0a%3c $ mkdir sources scripts docs%0a%3c $ mv *.lisp sources/%0a%3c $ ls%0a%3c README.md docs scripts sources test-hunchentoot.asd%0a%3c $%0a%3c @]%0a%3c %0a%3c So we leave .lisp files inside the sources/ directory and the system files on%0a%3c the project root directory. Now let's see what is inside the files created%0a%3c by quickproject, just pick test-hunchentoot.asd using emacs menu "File", then%0a%3c "Open File..." and choose the correct file navigating the user home directory:%0a%3c %0a%3c [@%0a%3c ;;;; test-hunchentoot.asd%0a%3c %0a%3c (asdf:defsystem #:testina-hunchentoot%0a%3c :description "Describe test-hunchentoot here"%0a%3c :author "antani %3cantani@antani.it>"%0a%3c :license "BSD"%0a%3c :version "0.0.1"%0a%3c :serial t%0a%3c :depends-on (#:cl-fad #:cl-who #:cl+ssl #:ironclad #:lass #:parenscript #:hunchentoot #:bordeaux-threads #:simple-date-time)%0a%3c :components ((:file "package")%0a%3c (:file "testina-hunchentoot")))%0a%3c @]%0a%3c %0a%3c We created a PEM certificate and a key, we can move them inside the project directory with:%0a%3c %0a%3c [@%0a%3c $ mv ~/selfsigned-crt.pem ~/Development/lisp/test-hunchentoot/scripts/%0a%3c $ mv ~/selfsigned-key.pem ~/Development/lisp/test-hunchentoot/scripts/%0a%3c $%0a%3c @]%0a%3c %0a%3c So we can reference them starting from the hunchentoot server document root%0a%3c directory. Before entering the application programming phase, we want to%0a%3c add legal notices (license) to the project files. We follow this convention:%0a%3c every file containing code related to system definitions and packaging will be%0a%3c marked with a license text, here an example test-hunchentoot.asd file in which%0a%3c the test-hunchentoot system is defined:%0a%3c %0a%3c [@%0a%3c ;;;;***************************************************************************%0a%3c ;;;; test-hunchentoot.asd%0a%3c ;;;;%0a%3c ;;;; Copyright 2023 Antani %3cantani@antani.it>%0a%3c ;;;;%0a%3c ;;;; Redistribution and use in source and binary forms, with or without%0a%3c ;;;; modification, are permitted provided that the following conditions are met:%0a%3c ;;;;%0a%3c ;;;; 1. Redistributions of source code must retain the above copyright notice,%0a%3c ;;;; this list of conditions and the following disclaimer.%0a%3c ;;;;%0a%3c ;;;; 2. Redistributions in binary form must reproduce the above copyright%0a%3c ;;;; notice, this list of conditions and the following disclaimer in the%0a%3c ;;;; documentation and/or other materials provided with the distribution.%0a%3c ;;;;%0a%3c ;;;; 3. Neither the name of the copyright holder nor the names of its%0a%3c ;;;; contributors may be used to endorse or promote products derived from%0a%3c ;;;; this software without specific prior written permission.%0a%3c ;;;;%0a%3c ;;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND%0a%3c ;;;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED%0a%3c ;;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE%0a%3c ;;;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE%0a%3c ;;;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL%0a%3c ;;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR%0a%3c ;;;; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER%0a%3c ;;;; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,%0a%3c ;;;; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE%0a%3c ;;;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.%0a%3c ;;;;***************************************************************************%0a%3c %0a%3c (asdf:defsystem #:test-hunchentoot%0a%3c :description "Test hunchentoot server (SSL version)."%0a%3c :author "Antani %3cantani@antani.it>"%0a%3c :license "BSD"%0a%3c :depends-on (#:cl-fad%0a%3c #:cl-who%0a%3c #:cl+ssl%0a%3c #:ironclad%0a%3c #:lass%0a%3c #:parenscript%0a%3c #:hunchentoot%0a%3c #:bordeaux-threads%0a%3c #:simple-date-time)%0a%3c :serial t%0a%3c :components ((:file "sources/package")%0a%3c (:file "sources/parameters")%0a%3c (:file "sources/system")%0a%3c (:file "sources/test-hunchentoot")))%0a%3c %0a%3c ;; End of file test-hunchentoot.asd%0a%3c @]%0a%3c %0a%3c To automate the process of inserting this license text, we can create a text%0a%3c file and insert it in the source file we want to modify, for example let's call%0a%3c it LICENSE:%0a%3c %0a%3c [@%0a%3c ;;;; Copyright 2023 Antani %3cantani@antani.it>%0a%3c ;;;;%0a%3c ;;;; Redistribution and use in source and binary forms, with or without%0a%3c ;;;; modification, are permitted provided that the following conditions are met:%0a%3c ;;;;%0a%3c ;;;; 1. Redistributions of source code must retain the above copyright notice,%0a%3c ;;;; this list of conditions and the following disclaimer.%0a%3c ;;;;%0a%3c ;;;; 2. Redistributions in binary form must reproduce the above copyright%0a%3c ;;;; notice, this list of conditions and the following disclaimer in the%0a%3c ;;;; documentation and/or other materials provided with the distribution.%0a%3c ;;;;%0a%3c ;;;; 3. Neither the name of the copyright holder nor the names of its%0a%3c ;;;; contributors may be used to endorse or promote products derived from%0a%3c ;;;; this software without specific prior written permission.%0a%3c ;;;;%0a%3c ;;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND%0a%3c ;;;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED%0a%3c ;;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE%0a%3c ;;;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE%0a%3c ;;;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL%0a%3c ;;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR%0a%3c ;;;; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER%0a%3c ;;;; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,%0a%3c ;;;; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE%0a%3c ;;;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.%0a%3c ;;;;***************************************************************************%0a%3c @]%0a%3c %0a%3c so a source code file related to packaging and system definitions will have%0a%3c this shape:%0a%3c %0a%3c * a comment containing emacs configurations and mode for the file;%0a%3c * a separator;%0a%3c * the name of the file itself;%0a%3c * a separator;%0a%3c * the licensing information;%0a%3c * a separator;%0a%3c * source code;%0a%3c * an end of file comment.%0a%3c %0a%3c Other source code files, instead will have this shape:%0a%3c %0a%3c * a comment containing emacs configurations and mode for the file;%0a%3c * a separator;%0a%3c * the file name;%0a%3c * a description of the file contents;%0a%3c * a separator;%0a%3c * source code;%0a%3c * an end of file comment.%0a%3c %0a%3c We remind you that in Common Lisp comments always begin with ";" until the end%0a%3c of the line. There are some conventions on the use of ";" itself. The%0a%3c following rules are taken from "Google Common Lisp Style Guide" at%0a%3c [[https://google.github.io/styleguide/lispguide.xml]]%0a%3c %0a%3c * File headers and important comments that apply to large sections of code in a source file should begin with four semicolons.%0a%3c * You should use three semicolons to begin comments that apply to just one top-level form or small group of top-level forms.%0a%3c * Inside a top-level form, you should use two semicolons to begin a comment if it appears between lines.%0a%3c * You should use one semicolon if it is a parenthetical remark and occurs at the end of a line. You should use spaces to separate the comment from the code it refers to so the comment stands out. You should try to vertically align consecutive related end-of-line comments.%0a%3c %0a%3c The complete project would appear as follows:%0a%3c %0a%3c [@%0a%3c $ tree%0a%3c .%0a%3c |-- LICENCE%0a%3c |-- README%0a%3c |-- scripts%0a%3c | |-- run-webserver.sh%0a%3c | |-- selfsigned-crt.pem%0a%3c | `-- selfsigned-key.pem%0a%3c |-- sources%0a%3c | |-- package.lisp%0a%3c | |-- parameters.lisp%0a%3c | |-- system.lisp%0a%3c | `-- test-hunchentoot.lisp%0a%3c `-- test-hunchentoot.asd%0a%3c %0a%3c 2 directories, 10 files%0a%3c $%0a%3c @]%0a%3c %0a%3c File are listed as follows. For the package.lisp file in sources/:%0a%3c %0a%3c [@%0a%3c ;;;; -*- mode: common-lisp-mode; electric-indent-mode: t; coding: utf-8 -*-%0a%3c ;;;;***************************************************************************%0a%3c ;;;; package.lisp%0a%3c ;;;;***************************************************************************%0a%3c ;;;; Copyright 2023 Antani %3cantani@antani.it>%0a%3c ;;;;%0a%3c ;;;; Redistribution and use in source and binary forms, with or without%0a%3c ;;;; modification, are permitted provided that the following conditions are met:%0a%3c ;;;;%0a%3c ;;;; 1. Redistributions of source code must retain the above copyright notice,%0a%3c ;;;; this list of conditions and the following disclaimer.%0a%3c ;;;;%0a%3c ;;;; 2. Redistributions in binary form must reproduce the above copyright%0a%3c ;;;; notice, this list of conditions and the following disclaimer in the%0a%3c ;;;; documentation and/or other materials provided with the distribution.%0a%3c ;;;;%0a%3c ;;;; 3. Neither the name of the copyright holder nor the names of its%0a%3c ;;;; contributors may be used to endorse or promote products derived from%0a%3c ;;;; this software without specific prior written permission.%0a%3c ;;;;%0a%3c ;;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND%0a%3c ;;;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED%0a%3c ;;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE%0a%3c ;;;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE%0a%3c ;;;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL%0a%3c ;;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR%0a%3c ;;;; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER%0a%3c ;;;; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,%0a%3c ;;;; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE%0a%3c ;;;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.%0a%3c ;;;;***************************************************************************%0a%3c %0a%3c (defpackage #:test-hunchentoot%0a%3c (:use #:cl)%0a%3c (:export #:start-web-server%0a%3c #:stop-web-server))%0a%3c %0a%3c ;;;; End of file package.lisp%0a%3c @]%0a%3c %0a%3c For the parameters.lisp file in sources/:%0a%3c %0a%3c [@%0a%3c ;;;; -*- mode: common-lisp-mode; electric-indent-mode: t; coding: utf-8 -*-%0a%3c ;;;;***************************************************************************%0a%3c ;;;; parameters.lisp%0a%3c ;;;;***************************************************************************%0a%3c ;;;; Parameters and variables definitions for the project test-hunchentoot.%0a%3c ;;;;***************************************************************************%0a%3c %0a%3c (in-package #:test-hunchentoot)%0a%3c %0a%3c ;;;; Parameters.%0a%3c (defparameter *ssl-acceptor* nil)%0a%3c (defparameter *default-document-root-directory-pathname* (cl-fad:merge-pathnames-as-directory (user-homedir-pathname) #p"Development/lisp/test-hunchentoot/"))%0a%3c (defparameter *default-ssl-private-key-file-pathname* (cl-fad:merge-pathnames-as-file (user-homedir-pathname) #p"Development/lisp/test-hunchentoot/scripts/selfsigned-key.pem"))%0a%3c (defparameter *default-ssl-certificate-file-pathname* (cl-fad:merge-pathnames-as-file (user-homedir-pathname) #p"Development/lisp/test-hunchentoot/scripts/selfsigned-crt.pem"))%0a%3c (defparameter *default-port* 4242)%0a%3c (defparameter *default-ssl-port* 9443)%0a%3c (defparameter *port* 4242)%0a%3c (defparameter *ssl-port* 9443)%0a%3c (defparameter *default-start-page-reload-timeout* 0)%0a%3c (defparameter *default-info-email* "antani@antani.it")%0a%3c (defparameter *fruits* '(apple pear banana orange avocado pineapple peach plum))%0a%3c %0a%3c ;;;; End of file parameters.lisp%0a%3c @]%0a%3c %0a%3c For the system.lisp file in sources/:%0a%3c %0a%3c [@%0a%3c ;;;; -*- mode: common-lisp-mode; electric-indent-mode: t; coding: utf-8 -*-%0a%3c ;;;;***************************************************************************%0a%3c ;;;; system.lisp%0a%3c ;;;;***************************************************************************%0a%3c ;;;; Provide data structures and classes definitions for the project%0a%3c ;;;; test-hunchentoot.%0a%3c ;;;;***************************************************************************%0a%3c %0a%3c (in-package #:test-hunchentoot)%0a%3c %0a%3c ;; System class.%0a%3c (defclass system-class ()%0a%3c ((acceptor :initarg :acceptor :accessor acceptor :initform nil)%0a%3c (ssl-acceptor :initarg :ssl-acceptor :accessor ssl-acceptor :initform nil)%0a%3c (lock-object :initarg :lock-object :accessor lock-object :initform nil)%0a%3c (condition-object :initarg :condition-object :accessor condition-object :initform nil)))%0a%3c %0a%3c ;; functions.%0a%3c %0a%3c (defun make-system (&rest parameters &key (acceptor nil acceptor-p) (ssl-acceptor nil ssl-acceptor-p) (lock-object nil lock-object-p) (condition-object nil condition-object-p))%0a%3c "Create an instance of the system-class."%0a%3c (declare (ignorable parameters%0a%3c acceptor%0a%3c ssl-acceptor%0a%3c lock-object%0a%3c condition-object))%0a%3c (make-instance 'system-class%0a%3c :acceptor acceptor%0a%3c :ssl-acceptor ssl-acceptor%0a%3c :lock-object lock-object%0a%3c :condition-object condition-object))%0a%3c %0a%3c ;;;; End of file system.lisp%0a%3c @]%0a%3c %0a%3c For the test-hunchentoot.lisp file in sources/:%0a%3c %0a%3c [@%0a%3c ;;;; -*- mode: common-lisp-mode; electric-indent-mode: t; coding: utf-8 -*-%0a%3c ;;;;***************************************************************************%0a%3c ;;;; test-hunchentoot.lisp%0a%3c ;;;;***************************************************************************%0a%3c ;;;; This file contains all the functions for the test-hunchentoot project.%0a%3c ;;;;***************************************************************************%0a%3c ;;;;%0a%3c %0a%3c (in-package #:test-hunchentoot)%0a%3c %0a%3c ;; Initial setup for javascript environment%0a%3c (eval-when (:compile-toplevel :execute)%0a%3c (setq cl-who:*attribute-quote-char* #\"%0a%3c ps:*js-string-delimiter* #\"))%0a%3c ;; "test-hunchentoot" goes here. Hacks and glory await!%0a%3c ;; Methods.%0a%3c (defmethod hunchentoot:acceptor-dispatch-request ((vhost system-class) request)%0a%3c (mapc (lambda (dispatcher)%0a%3c (let ((handler (funcall dispatcher request)))%0a%3c (when handler%0a%3c (return-from hunchentoot:acceptor-dispatch-request (funcall handler)))))%0a%3c (dispatch-table vhost))%0a%3c (call-next-method))%0a%3c ;;%0a%3c (defmethod start-web-server ((object system-class) &rest parameters &key %0a%3c (document-root-directory-pathname *default-document-root-directory-pathname* document-root-directory-pathname-p)%0a%3c (ssl-private-key-file-pathname *default-ssl-private-key-file-pathname* ssl-private-key-file-pathname-p)%0a%3c (ssl-certificate-file-pathname *default-ssl-certificate-file-pathname* ssl-certificate-file-pathname-p)%0a%3c (address "localhost" address-p)%0a%3c (port *default-port* port-p)%0a%3c (ssl-port *default-ssl-port* ssl-port-p)%0a%3c (page-reload-timeout *default-start-page-reload-timeout* page-reload-timeout-p)%0a%3c (verbose nil))%0a%3c "Configure and start the hunchentoot webserver."%0a%3c (declare (ignorable parameters%0a%3c document-root-directory-pathname%0a%3c ssl-private-key-file-pathname%0a%3c ssl-certificate-file-pathname%0a%3c address%0a%3c port%0a%3c ssl-port%0a%3c page-reload-timeout%0a%3c verbose))%0a%3c (when document-root-directory-pathname-p%0a%3c (check-type document-root-directory-pathname pathname)%0a%3c (assert (cl-fad:directory-exists-p document-root-directory-pathname)))%0a%3c (when ssl-private-key-file-pathname-p%0a%3c (check-type ssl-private-key-file-pathname pathname)%0a%3c (assert (cl-fad:file-exists-p ssl-private-key-file-pathname)))%0a%3c (when ssl-certificate-file-pathname-p%0a%3c (check-type ssl-certificate-file-pathname pathname)%0a%3c (assert (cl-fad:file-exists-p ssl-certificate-file-pathname)))%0a%3c (when address-p%0a%3c (check-type address string))%0a%3c (when port-p%0a%3c (check-type port (unsigned-byte 16)))%0a%3c (when ssl-port-p%0a%3c (check-type ssl-port (unsigned-byte 16)))%0a%3c (when (and port-p ssl-port-p)%0a%3c (assert (/= port ssl-port)))%0a%3c (when page-reload-timeout-p%0a%3c (check-type page-reload-timeout (unsigned-byte 16)))%0a%3c ;;%0a%3c (setq *random-state* (make-random-state t))%0a%3c (unwind-protect%0a%3c (let* ((hunchentoot:*log-lisp-errors-p* t)%0a%3c (hunchentoot:*log-lisp-warnings-p* t)%0a%3c (hunchentoot:*catch-errors-p* nil)%0a%3c (stdin (sb-sys:make-fd-stream 0%0a%3c :input t%0a%3c :buffering :full%0a%3c :element-type '(unsigned-byte 8)))%0a%3c (cl+ssl:make-ssl-client-stream (cl+ssl:stream-fd stdin)))%0a%3c (setf (lock-object object) (bt:make-lock (symbol-name (gensym "webserver-lock-"))))%0a%3c (setf (condition-object object) (bt:make-condition-variable :name (symbol-name (gensym "webserver-condition-"))))%0a%3c ;; Server setup and start%0a%3c (setf (ssl-acceptor object) (make-instance 'hunchentoot:easy-ssl-acceptor%0a%3c :name 'ssl-acceptor%0a%3c :ssl-privatekey-file ssl-private-key-file-pathname%0a%3c :ssl-certificate-file ssl-certificate-file-pathname%0a%3c :address address%0a%3c :port ssl-port%0a%3c :document-root document-root-directory-pathname))%0a%3c (hunchentoot:start (ssl-acceptor object))%0a%3c (setq *ssl-acceptor* (ssl-acceptor object))%0a%3c (when verbose%0a%3c (format *standard-output*%0a%3c "~%25;; Starting SSL Web Server on port ~a.~%25~%25" ssl-port)%0a%3c (format *standard-output*%0a%3c ";; Certificate pathname ~s.~%25" ssl-certificate-file-pathname)%0a%3c (format *standard-output*%0a%3c ";; Private key pathname ~s.~%25~%25" ssl-private-key-file-pathname)%0a%3c (finish-output *standard-output*))%0a%3c (setq hunchentoot:*dispatch-table* (list 'hunchentoot:dispatch-easy-handlers))%0a%3c (loop%0a%3c named wait-loop%0a%3c do%0a%3c (handler-case%0a%3c (progn%0a%3c (bt:with-lock-held ((lock-object object))%0a%3c (bt:condition-wait (condition-object object)%0a%3c (lock-object object)))%0a%3c (return-from wait-loop))%0a%3c (hunchentoot:hunchentoot-error (he)%0a%3c (format *standard-output* "~s~%25" he)%0a%3c (finish-output *standard-output*))%0a%3c (error (e)%0a%3c (format *standard-output* "~s~%25" e)%0a%3c (finish-output *standard-output*)%0a%3c (return-from wait-loop))%0a%3c (warning (w)%0a%3c (format *standard-output* "~s~%25" w)%0a%3c (finish-output *standard-output*)))))%0a%3c ;; unwind-protect cleanup form.%0a%3c (progn%0a%3c (when verbose%0a%3c (format *standard-output* ";; Shutting down webserver.~%25")%0a%3c (finish-output *standard-output*))%0a%3c (stop-web-server object :verbose t))))%0a%3c %0a%3c (defmethod stop-web-server ((object system-class) &rest parameters &key (verbose nil))%0a%3c "Stop the hunchentoot webserver."%0a%3c (declare (ignorable parameters verbose))%0a%3c (when (ssl-acceptor object)%0a%3c (hunchentoot:stop (ssl-acceptor object))%0a%3c (setq *ssl-acceptor* nil)%0a%3c (when verbose%0a%3c (format *standard-output*%0a%3c "~%25;; Stopping SSL Web Server.~%25~%25")%0a%3c (finish-output *standard-output*)))%0a%3c (bt:condition-notify (condition-object object)))%0a%3c %0a%3c ;; Functions.%0a%3c (defun remove-nth (index object)%0a%3c "remove the nth element from the list."%0a%3c (remove-if (constantly t)%0a%3c object%0a%3c :start index%0a%3c :count 1))%0a%3c %0a%3c ;; Hunchentoot html stuffs.%0a%3c (hunchentoot:define-easy-handler (main-page :uri "/") ()%0a%3c "The main page handler for http request."%0a%3c (hunchentoot:redirect "/index"))%0a%3c %0a%3c (hunchentoot:define-easy-handler (index-page :uri "/index") ()%0a%3c "The /index page handler for http request."%0a%3c (let ((temporary-fruits *fruits*)%0a%3c (i nil))%0a%3c (cl-who:with-html-output-to-string (s)%0a%3c (cl-who:htm%0a%3c (:html%0a%3c (:h1 "This is an example of dynamic list:")%0a%3c (:br)%0a%3c (:ul%0a%3c (loop%0a%3c while (> (length temporary-fruits) 0)%0a%3c do%0a%3c (setq i (random (length temporary-fruits)))%0a%3c (cl-who:htm%0a%3c (:li (cl-who:str (nth i temporary-fruits))))%0a%3c (setq temporary-fruits (remove-nth i temporary-fruits)))))))))%0a%3c %0a%3c ;; Start at quickload.%0a%3c (start-web-server (make-system)%0a%3c :ssl-port *default-ssl-port*%0a%3c :verbose t)%0a%3c %0a%3c ;;;; End of file test-hunchentoot.lisp%0a%3c @]%0a\ No newline at end of file%0a
49 host:1700849198=93.45.233.109
50 author:1700847574=Posterdati
51 diff:1700847574:1700847312:=356,378c356,379%0a%3c [@%0a%3c $ sbcl%0a%3c ...%0a%3c * (ql:quickload :quicklisp-slime-helper)%0a%3c To load "quicklisp-slime-helper":%0a%3c Load 1 ASDF system:%0a%3c quicklisp-slime-helper%0a%3c ; Loading "quicklisp-slime-helper"%0a%3c [package swank-loader]............................%0a%3c [package quicklisp-slime-helper]%0a%3c slime-helper.el installed in "/home/user/quicklisp/slime-helper.el"%0a%3c %0a%3c To use, add this to your ~/.emacs:%0a%3c %0a%3c (load (expand-file-name "/home/user/quicklisp/slime-helper.el"))%0a%3c ;; Replace "sbcl" with the path to your implementation%0a%3c (setq inferior-lisp-program "sbcl")%0a%3c %0a%3c %0a%3c (:QUICKLISP-SLIME-HELPER)%0a%3c *%0a%3c @]%0a%3c %0a---%0a> .. code::%0a> %0a> $ sbcl%0a> ...%0a> * (ql:quickload :quicklisp-slime-helper)%0a> To load "quicklisp-slime-helper":%0a> Load 1 ASDF system:%0a> quicklisp-slime-helper%0a> ; Loading "quicklisp-slime-helper"%0a> [package swank-loader]............................%0a> [package quicklisp-slime-helper]%0a> slime-helper.el installed in "/home/user/quicklisp/slime-helper.el"%0a> %0a> To use, add this to your ~/.emacs:%0a> %0a> (load (expand-file-name "/home/user/quicklisp/slime-helper.el"))%0a> ;; Replace "sbcl" with the path to your implementation%0a> (setq inferior-lisp-program "sbcl")%0a> %0a> %0a> (:QUICKLISP-SLIME-HELPER)%0a> *%0a> %0a> %0a382,387c383,390%0a%3c [@%0a%3c (load (expand-file-name "/home/user/quicklisp/slime-helper.el"))%0a%3c ;; Replace "sbcl" with the path to your implementation%0a%3c (setq inferior-lisp-program "sbcl")%0a%3c @]%0a%3c %0a---%0a> %0a> .. code:: common-lisp%0a> %0a> (load (expand-file-name "/home/user/quicklisp/slime-helper.el"))%0a> ;; Replace "sbcl" with the path to your implementation%0a> (setq inferior-lisp-program "sbcl")%0a> %0a> %0a421,427c424,432%0a%3c [@%0a%3c CL-USER> (ql:quickload :antik)%0a%3c ...%0a%3c (:ANTIK)%0a%3c CL-USER>%0a%3c @]%0a%3c %0a---%0a> %0a> .. code:: common-lisp%0a> %0a> CL-USER> (ql:quickload :antik)%0a> ...%0a> (:ANTIK)%0a> CL-USER>%0a> %0a> %0a431,436c436,454%0a%3c [@%0a%3c CL-USER> antik:+days-per-month+%0a%3c 30%0a%3c CL-USER>%0a%3c @]%0a%3c %0a---%0a> %0a> .. code:: common-lisp%0a> %0a> CL-USER> antik:+days-per-month+%0a> 30%0a> CL-USER>%0a> %0a> %0a> .. raw:: pdf%0a> %0a> PageBreak%0a> %0a> %0a> .. raw:: pdf%0a> %0a> OddPageBreak%0a> %0a> %0a> .. comment: End of file.%0a
52 host:1700847574=93.45.233.109
53 author:1700847312=Posterdati
54 diff:1700847312:1700846904:=273,289c273,289%0a%3c [@%0a%3c * (ql:add-to-init-file)%0a%3c I will append the following lines to #P"/home/user/.sbclrc":%0a%3c %0a%3c ;;; The following lines added by ql:add-to-init-file:%0a%3c #-quicklisp%0a%3c (let ((quicklisp-init #P"/home/user/quicklisp/setup.lisp"))%0a%3c (when (probe-file quicklisp-init)%0a%3c (load quicklisp-init)))%0a%3c %0a%3c Press Enter to continue.%0a%3c %0a%3c #P"/home/user/.sbclrc"%0a%3c * (quit)%0a%3c $%0a%3c @]%0a%3c %0a---%0a> %0a> .. code::%0a> %0a> * (ql:add-to-init-file)%0a> I will append the following lines to #P"/home/user/.sbclrc":%0a> %0a> ;;; The following lines added by ql:add-to-init-file:%0a> #-quicklisp%0a> (let ((quicklisp-init #P"/home/user/quicklisp/setup.lisp"))%0a> (when (probe-file quicklisp-init)%0a> (load quicklisp-init)))%0a> %0a> Press Enter to continue.%0a> %0a> #P"/home/user/.sbclrc"%0a> * (quit)%0a> %0a293,301c293,307%0a%3c [@%0a%3c $ cat ~/.sbclrc%0a%3c ;;; The following lines added by ql:add-to-init-file:%0a%3c #-quicklisp%0a%3c (let ((quicklisp-init #P"/home/user/quicklisp/setup.lisp"))%0a%3c (when (probe-file quicklisp-init)%0a%3c (load quicklisp-init)))%0a%3c @]%0a%3c %0a---%0a> .. code::%0a> %0a> $ cat ~/.sbclrc%0a> ;;; The following lines added by ql:add-to-init-file:%0a> #-quicklisp%0a> (let ((quicklisp-init #P"/home/user/quicklisp/setup.lisp"))%0a> (when (probe-file quicklisp-init)%0a> (load quicklisp-init)))%0a> %0a> %0a> .. raw:: pdf%0a> %0a> PageBreak%0a> %0a> %0a303c309%0a%3c REPL, we can place configuration code for sbcl in there. For example we want%0a---%0a> REPL, we can place configuration for sbcl code in there, for example we want%0a308,322c314,330%0a%3c [@%0a%3c (defun setup-registry (directory-path)%0a%3c (format t "; adding components under ~A to asdf registry~%25" directory-path)%0a%3c (mapc (lambda (asd-pathname)%0a%3c (pushnew (make-pathname :name nil%0a%3c :type nil%0a%3c :version nil%0a%3c :defaults asd-pathname)%0a%3c asdf:*central-registry*%0a%3c :test #'equal))%0a%3c (directory (merge-pathnames #p"**/*.asd" directory-path))))%0a%3c %0a%3c (setup-registry (merge-pathnames #p"Development/lisp/" (user-homedir-pathname)))%0a%3c @]%0a%3c %0a---%0a> %0a> .. code:: common-lisp%0a> %0a> (defun setup-registry (directory-path)%0a> (format t "; adding components under ~A to asdf registry~%25" directory-path)%0a> (mapc (lambda (asd-pathname)%0a> (pushnew (make-pathname :name nil%0a> :type nil%0a> :version nil%0a> :defaults asd-pathname)%0a> asdf:*central-registry*%0a> :test #'equal))%0a> (directory (merge-pathnames #p"**/*.asd" directory-path))))%0a> %0a> (setup-registry (merge-pathnames #p"Development/lisp/" (user-homedir-pathname)))%0a> %0a> %0a325,337c333,346%0a%3c [@%0a%3c $ sbcl%0a%3c This is SBCL 2.3.8.openbsd.sbcl-2.3.8, an implementation of ANSI Common Lisp.%0a%3c More information about SBCL is available at %3chttp://www.sbcl.org/>.%0a%3c %0a%3c SBCL is free software, provided as is, with absolutely no warranty.%0a%3c It is mostly in the public domain; some portions are provided under%0a%3c BSD-style licenses. See the CREDITS and COPYING files in the%0a%3c distribution for more information.%0a%3c ; adding components under /home/angel/Development/lisp/ to asdf registry%0a%3c *%0a%3c @]%0a%3c %0a---%0a> .. code:: shell%0a> %0a> $ sbcl%0a> This is SBCL 2.3.8.openbsd.sbcl-2.3.8, an implementation of ANSI Common Lisp.%0a> More information about SBCL is available at %3chttp://www.sbcl.org/>.%0a> %0a> SBCL is free software, provided as is, with absolutely no warranty.%0a> It is mostly in the public domain; some portions are provided under%0a> BSD-style licenses. See the CREDITS and COPYING files in the%0a> distribution for more information.%0a> ; adding components under /home/angel/Development/lisp/ to asdf registry%0a> *%0a> %0a> %0a340,350c349,366%0a%3c [@%0a%3c * *features*%0a%3c (:QUICKLISP :ASDF3.3 :ASDF3.2 :ASDF3.1 :ASDF3 :ASDF2 :ASDF :OS-UNIX%0a%3c :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :ARENA-ALLOCATOR :X86-64 :GENCGC :64-BIT%0a%3c :ANSI-CL :BSD :COMMON-LISP :ELF :IEEE-FLOATING-POINT :LITTLE-ENDIAN :OPENBSD%0a%3c :PACKAGE-LOCAL-NICKNAMES :SB-CORE-COMPRESSION :SB-LDB :SB-PACKAGE-LOCKS%0a%3c :SB-THREAD :SB-UNICODE :SBCL :UNIX)%0a%3c *%0a%3c @]%0a%3c %0a%3c !!'''Configuration for emacs'''%0a---%0a> .. code:: common-lisp%0a> %0a> * *features*%0a> (:QUICKLISP :ASDF3.3 :ASDF3.2 :ASDF3.1 :ASDF3 :ASDF2 :ASDF :OS-UNIX%0a> :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :ARENA-ALLOCATOR :X86-64 :GENCGC :64-BIT%0a> :ANSI-CL :BSD :COMMON-LISP :ELF :IEEE-FLOATING-POINT :LITTLE-ENDIAN :OPENBSD%0a> :PACKAGE-LOCAL-NICKNAMES :SB-CORE-COMPRESSION :SB-LDB :SB-PACKAGE-LOCKS%0a> :SB-THREAD :SB-UNICODE :SBCL :UNIX)%0a> *%0a> %0a> %0a> .. raw:: pdf%0a> %0a> PageBreak%0a> %0a> %0a> Configuration for emacs%0a> -----------------------%0a
55 host:1700847312=93.45.233.109
56 author:1700846904=Posterdati
57 diff:1700846904:1700846567:=122,126c122,124%0a%3c [@%0a%3c $ doas pkg_add -v bash%0a%3c @]%0a%3c %0a%3c %0a---%0a> @@$ doas pkg_add -v bash@@%0a> %0a> %0a131,135c129,131%0a%3c [@%0a%3c $ doas pkg_add -v sbcl%0a%3c @]%0a%3c %0a%3c %0a---%0a> @@$ doas pkg_add -v sbcl@@%0a> %0a> %0a141,144c137,138%0a%3c [@%0a%3c $ sbcl%0a%3c @]%0a%3c %0a---%0a> @@$ sbcl@@%0a> %0a147,156c141,150%0a%3c [@%0a%3c This is SBCL 2.3.8.openbsd.sbcl-2.3.8, an implementation of ANSI Common Lisp.%0a%3c More information about SBCL is available at %3chttp://www.sbcl.org/>.%0a%3c SBCL is free software, provided as is, with absolutely no warranty.%0a%3c It is mostly in the public domain; some portions are provided under%0a%3c BSD-style licenses. See the CREDITS and COPYING files in the%0a%3c distribution for more information.%0a%3c *%0a%3c @]%0a%3c %0a---%0a> ----%0a> @@This is SBCL 2.3.8.openbsd.sbcl-2.3.8, an implementation of ANSI Common Lisp.@@\\%0a> @@More information about SBCL is available at %3chttp://www.sbcl.org/>.@@\\%0a> @@SBCL is free software, provided as is, with absolutely no warranty.@@\\%0a> @@It is mostly in the public domain; some portions are provided under@@\\%0a> @@BSD-style licenses. See the CREDITS and COPYING files in the@@\\%0a> @@distribution for more information.@@\\%0a> @@*@@%0a> ----%0a> %0a166a161%0a> ----%0a174c169,170%0a%3c %0a---%0a> ----%0a> %0a183,186c179,182%0a%3c [@%0a%3c $ doas pkg_add -v emacs%0a%3c @]%0a%3c %0a---%0a> ----%0a> @@$ doas pkg_add -v emacs@@%0a> ----%0a> %0a198,203c194,199%0a%3c from the site [[https://beta.quicklisp.org]]. We use curl to do that, so:%0a%3c %0a%3c [@%0a%3c $ doas pkg_add -v curl%0a%3c @]%0a%3c %0a---%0a> from the site `%3chttps://beta.quicklisp.org>`_ . We use curl to do that, so:%0a> %0a> ----%0a> @@$ doas pkg_add -v curl@@%0a> ----%0a> %0a206,209c202,205%0a%3c [@%0a%3c $ curl -O https://beta.quicklisp.org/quicklisp.lisp%0a%3c @]%0a%3c %0a---%0a> ----%0a> @@$ curl -O https://beta.quicklisp.org/quicklisp.lisp@@%0a> ----%0a> %0a212,215c208,211%0a%3c [@%0a%3c $ curl -O https://beta.quicklisp.org/quicklisp.lisp.asc%0a%3c @]%0a%3c %0a---%0a> ----%0a> @@$ curl -O https://beta.quicklisp.org/quicklisp.lisp.asc@@%0a> ----%0a> %0a218,223c214,219%0a%3c [@%0a%3c $ gpg --verify quicklisp.lisp.asc quicklisp.lisp%0a%3c gpg: Signature made Sat Feb 1 09:25:28 2014 EST using RSA key ID 028B5FF7%0a%3c gpg: Good signature from "Quicklisp Release Signing Key "%0a%3c @]%0a%3c %0a---%0a> ----%0a> @@$ gpg --verify quicklisp.lisp.asc quicklisp.lisp@@\\%0a> @@gpg: Signature made Sat Feb 1 09:25:28 2014 EST using RSA key ID 028B5FF7@@\\%0a> @@gpg: Good signature from "Quicklisp Release Signing Key "@@\\%0a> ----%0a> %0a229,248c225,249%0a%3c [@%0a%3c %0a%3c $ sbcl --load quicklisp.lisp%0a%3c This is SBCL 2.3.8.openbsd.sbcl-2.3.8, an implementation of ANSI Common Lisp.%0a%3c More information about SBCL is available at %3chttp://www.sbcl.org/>.%0a%3c %0a%3c SBCL is free software, provided as is, with absolutely no warranty.%0a%3c It is mostly in the public domain; some portions are provided under%0a%3c BSD-style licenses. See the CREDITS and COPYING files in the%0a%3c distribution for more information.%0a%3c %0a%3c ==== quicklisp quickstart 2015-01-28 loaded ====%0a%3c %0a%3c To continue with installation, evaluate: (quicklisp-quickstart:install)%0a%3c %0a%3c For installation options, evaluate: (quicklisp-quickstart:help)%0a%3c %0a%3c *%0a%3c @]%0a%3c %0a---%0a> %0a> .. code::%0a> %0a> $ sbcl --load quicklisp.lisp%0a> This is SBCL 2.3.8.openbsd.sbcl-2.3.8, an implementation of ANSI Common Lisp.%0a> More information about SBCL is available at %3chttp://www.sbcl.org/>.%0a> %0a> SBCL is free software, provided as is, with absolutely no warranty.%0a> It is mostly in the public domain; some portions are provided under%0a> BSD-style licenses. See the CREDITS and COPYING files in the%0a> distribution for more information.%0a> %0a> ==== quicklisp quickstart 2015-01-28 loaded ====%0a> %0a> To continue with installation, evaluate: (quicklisp-quickstart:install)%0a> %0a> For installation options, evaluate: (quicklisp-quickstart:help)%0a> %0a> *%0a> %0a> .. raw:: pdf%0a> %0a> PageBreak%0a> %0a> %0a251,266c252,268%0a%3c [@%0a%3c * (quicklisp-quickstart:install)%0a%3c ...%0a%3c ==== quicklisp installed ====%0a%3c %0a%3c To load a system, use: (ql:quickload "system-name")%0a%3c %0a%3c To find systems, use: (ql:system-apropos "term")%0a%3c %0a%3c To load Quicklisp every time you start Lisp, use: (ql:add-to-init-file)%0a%3c %0a%3c For more information, see http://www.quicklisp.org/beta/%0a%3c %0a%3c T%0a%3c *%0a%3c @]%0a---%0a> .. code::%0a> %0a> * (quicklisp-quickstart:install)%0a> ...%0a> ==== quicklisp installed ====%0a> %0a> To load a system, use: (ql:quickload "system-name")%0a> %0a> To find systems, use: (ql:system-apropos "term")%0a> %0a> To load Quicklisp every time you start Lisp, use: (ql:add-to-init-file)%0a> %0a> For more information, see http://www.quicklisp.org/beta/%0a> %0a> T%0a> *%0a> %0a
58 host:1700846904=93.45.233.109
59 author:1700846567=Posterdati
60 diff:1700846567:1700845680:=152,153c152,153%0a%3c it is waiting for a command to be entered at the REPL prompt "*".%0a%3c %0a---%0a> it is waiting for a command to be entered at the REPL prompt \*.\\%0a> %0a162,168c162,167%0a%3c [@%0a%3c * *features*%0a%3c (:ARENA-ALLOCATOR :X86-64 :GENCGC :64-BIT :ANSI-CL :BSD :COMMON-LISP :ELF%0a%3c :IEEE-FLOATING-POINT :LITTLE-ENDIAN :OPENBSD :PACKAGE-LOCAL-NICKNAMES%0a%3c :SB-CORE-COMPRESSION :SB-LDB :SB-PACKAGE-LOCKS :SB-THREAD :SB-UNICODE :SBCL%0a%3c :UNIX)%0a%3c @]%0a---%0a> @@* *features*@@\\%0a> @@(:ARENA-ALLOCATOR :X86-64 :GENCGC :64-BIT :ANSI-CL :BSD :COMMON-LISP :ELF@@\\%0a> @@ :IEEE-FLOATING-POINT :LITTLE-ENDIAN :OPENBSD :PACKAGE-LOCAL-NICKNAMES@\\%0a> @@ :SB-CORE-COMPRESSION :SB-LDB :SB-PACKAGE-LOCKS :SB-THREAD :SB-UNICODE :SBCL@\\%0a> @@ :UNIX)@@\\%0a> @@*@@%0a
61 host:1700846567=93.45.233.109
62 author:1700845680=Posterdati
63 diff:1700845680:1700845532:=170,171c170,172%0a%3c !!'''Installing quicklisp'''%0a%3c %0a---%0a> Installing quicklisp%0a> --------------------%0a> %0a178,181c179,183%0a%3c ----%0a%3c @@$ doas pkg_add -v emacs@@%0a%3c ----%0a%3c %0a---%0a> .. code:: shell%0a> %0a> $ doas pkg_add -v emacs%0a> %0a> %0a195,198c197,202%0a%3c ----%0a%3c @@$ doas pkg_add -v curl@@%0a%3c ----%0a%3c %0a---%0a> %0a> .. code:: shell%0a> %0a> $ doas pkg_add -v curl%0a> %0a> %0a201,204c205,209%0a%3c ----%0a%3c @@$ curl -O https://beta.quicklisp.org/quicklisp.lisp@@%0a%3c ----%0a%3c %0a---%0a> .. code:: shell%0a> %0a> curl -O https://beta.quicklisp.org/quicklisp.lisp%0a> %0a> %0a207,210c212,217%0a%3c ----%0a%3c @@$ curl -O https://beta.quicklisp.org/quicklisp.lisp.asc@@%0a%3c ----%0a%3c %0a---%0a> %0a> .. code:: shell%0a> %0a> $ curl -O https://beta.quicklisp.org/quicklisp.lisp.asc%0a> %0a> %0a213,217c220,226%0a%3c ----%0a%3c @@$ gpg --verify quicklisp.lisp.asc quicklisp.lisp@@\\%0a%3c @@gpg: Signature made Sat Feb 1 09:25:28 2014 EST using RSA key ID 028B5FF7@@\\%0a%3c @@gpg: Good signature from "Quicklisp Release Signing Key "@@\\%0a%3c ----%0a---%0a> %0a> .. code:: shell%0a> %0a> $ gpg --verify quicklisp.lisp.asc quicklisp.lisp%0a> gpg: Signature made Sat Feb 1 09:25:28 2014 EST using RSA key ID 028B5FF7%0a> gpg: Good signature from "Quicklisp Release Signing Key "%0a> %0a
64 host:1700845680=93.45.233.109
65 author:1700845532=Posterdati
66 diff:1700845532:1700845404:=15c15%0a%3c !!!'''License Information'''%0a---%0a> !!!'''License Information''''%0a
67 host:1700845532=93.45.233.109
68 author:1700845404=Posterdati
69 diff:1700845404:1700844753:=3,4c3,6%0a%3c !!'''With a simple Hunchentoot example'''%0a%3c %0a---%0a> ---------------------------------%0a> !! With a simple Hunchentoot example%0a> ---------------------------------%0a> %0a11,12c13,14%0a%3c !!!'''Preface to this Edition'''%0a%3c %0a---%0a> !!!Preface to this Edition%0a> %0a15,16c17,18%0a%3c !!!'''License Information''''%0a%3c %0a---%0a> !!!License Information%0a> %0a47,48c49,50%0a%3c !'''Introduction'''%0a%3c %0a---%0a> !Introduction%0a> %0a66,67c68,69%0a%3c !!'''Foreword'''%0a%3c %0a---%0a> !!Foreword%0a> %0a84,85c86,87%0a%3c !!'''Who is this guide for?'''%0a%3c %0a---%0a> !!Who is this guide for?%0a> %0a96,97c98,99%0a%3c !!'''Other resources'''%0a%3c %0a---%0a> !!Other resources%0a> %0a107,108c109,110%0a%3c !!'''Legally speaking...'''%0a%3c %0a---%0a> !!Legally speaking...%0a> %0a111,114c113,119%0a%3c !'''Getting Started'''%0a%3c %0a%3c !!'''The installation process'''%0a%3c %0a---%0a> .. comment: -*- mode: rst-mode; coding: utf-8; electric-indent-mode: t; -*-%0a> %0a> %0a> !Getting Started%0a> %0a> !!The installation process%0a> %0a132,133c137,138%0a%3c !!'''Configuration for sbcl'''%0a%3c %0a---%0a> !!Configuration for sbcl%0a> %0a141d145%0a%3c ----%0a148,150c152,153%0a%3c @@*@@%0a%3c ----%0a%3c %0a---%0a> @@*@@\\%0a> %0a152,168c155,176%0a%3c it is waiting for a command to be entered at the REPL prompt \*.\\%0a%3c %0a%3c REPL stands for Read, Eval and Print Loop: a way to interact with a user.%0a%3c At first the informations entered after the prompt are read, then evaluated%0a%3c by the sbcl interpreter and a result is always printed/returned back to the%0a%3c user. The cycle continues with the interpreter waiting for the user to enter%0a%3c informations again. At this point we would like to see some configurations/characteristics%0a%3c of this particular version of the interpreter, so we enter:%0a%3c %0a%3c ----%0a%3c @@* *features*@@\\%0a%3c @@(:ARENA-ALLOCATOR :X86-64 :GENCGC :64-BIT :ANSI-CL :BSD :COMMON-LISP :ELF@@\\%0a%3c @@ :IEEE-FLOATING-POINT :LITTLE-ENDIAN :OPENBSD :PACKAGE-LOCAL-NICKNAMES@\\%0a%3c @@ :SB-CORE-COMPRESSION :SB-LDB :SB-PACKAGE-LOCKS :SB-THREAD :SB-UNICODE :SBCL@\\%0a%3c @@ :UNIX)@@\\%0a%3c @@*@@%0a%3c ----%0a---%0a> it is waiting for a command to be entered at the REPL [#]_ prompt \*. At this point%0a> we would like to see some configurations/characteristics of this particular%0a> version of the interpreter, so we enter:%0a> %0a> .. [#]%0a> %0a> REPL stands for Read, Eval and Print Loop: a way to interact with a user.%0a> At first the informations entered after the prompt are read, then evaluated%0a> by the sbcl interpreter and a result is always printed/returned back to the%0a> user. The cycle continues with the interpreter waiting for the user to enter%0a> informations again.%0a> %0a> %0a> .. code::%0a> %0a> * *features*%0a> (:ARENA-ALLOCATOR :X86-64 :GENCGC :64-BIT :ANSI-CL :BSD :COMMON-LISP :ELF%0a> :IEEE-FLOATING-POINT :LITTLE-ENDIAN :OPENBSD :PACKAGE-LOCAL-NICKNAMES%0a> :SB-CORE-COMPRESSION :SB-LDB :SB-PACKAGE-LOCKS :SB-THREAD :SB-UNICODE :SBCL%0a> :UNIX)%0a> *%0a> %0a
70 host:1700845404=93.45.233.109
71 author:1700844753=Posterdati
72 diff:1700844753:1700843694:=1,2c1,2%0a%3c !'''Common Lisp on OpenBSD'''%0a%3c %0a---%0a> !Common Lisp on OpenBSD%0a> %0a19,488c19,45%0a%3c Copyright (C) 2023 Angelo Rossi %3cangelo.rossi.homelab@gmail.com>\\%0a%3c %0a%3c %0a%3c Redistribution and use in source and binary forms, with or without\\%0a%3c modification, are permitted provided that the following conditions\\%0a%3c are met:\\%0a%3c %0a%3c %0a%3c 1. Redistributions of source code must retain the above copyright\\%0a%3c notice, this list of conditions and the following disclaimer.\\%0a%3c 2. Redistributions in binary form must reproduce the above copyright\\%0a%3c notice, this list of conditions and the following disclaimer in the\\%0a%3c documentation and/or other materials provided with the distribution.\\%0a%3c 3. Neither the name of the University nor the names of its contributors\\%0a%3c may be used to endorse or promote products derived from this software\\%0a%3c without specific prior written permission.\\%0a%3c %0a%3c %0a%3c THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\\%0a%3c ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\\%0a%3c IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\\%0a%3c ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\\%0a%3c FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\\%0a%3c DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\\%0a%3c OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\\%0a%3c HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\\%0a%3c LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\\%0a%3c OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\\%0a%3c SUCH DAMAGE.\\%0a%3c %0a%3c !Introduction%0a%3c %0a%3c This document explain how to install and configure sbcl on OpenBSD system.%0a%3c Assuming you already installed this OS on your machine with basic tools and%0a%3c desktop environment or, at least, you are able to use emacs as text editor.%0a%3c First of all OpenBSD is a free 4.4BSD-based Unix-like operating system. It has%0a%3c got these unique features:%0a%3c %0a%3c * portability;%0a%3c * standardization;%0a%3c * correctness;%0a%3c * proactive security;%0a%3c * integrated cryptography.%0a%3c %0a%3c For all of these you could be interested in run a webserver on it. So let's see%0a%3c how to achieve that and look at a simple way to program a dynamic webserver%0a%3c application which in turn use the Common Lisp language to create html pages on%0a%3c the fly.%0a%3c %0a%3c !!Foreword%0a%3c %0a%3c Why Common Lisp? One of the question that arises most of the times speaking%0a%3c with people involved in computer science as professionals or reasearches. Most%0a%3c of them look at Lisp (and Common Lisp as a reflex) not only the language%0a%3c developed for AI fifty years ago, but something strange and esotheric,%0a%3c something not really useful and related to a distant past made of punched cards%0a%3c and gigantic magnetic tape reader the size of a fridge. No one take Lisp as%0a%3c the language of the following innovations:%0a%3c %0a%3c * a regular and most simple syntax among high level programming language;%0a%3c * the first high level language used to program an OS (Genera);%0a%3c * used to program one of the first graphic user interface for an OS;%0a%3c * an advanced macro system to generate Lisp code and extend the language (DSL);%0a%3c * A garbage collector;%0a%3c * derived from the mathematics idea of lambda calculus by Alonzo Church;%0a%3c * a major dialect with a standard: ANSI INCITS 226-1994 (S20018).%0a%3c %0a%3c !!Who is this guide for?%0a%3c %0a%3c The purpose of this guide is to let the reader discovers one of the most%0a%3c advanced and complete language in the history of computer science. The usage%0a%3c of Lisp is quite simple since it is based on very basic ideas about%0a%3c programming. Since OpenBSD is a modern UNIX OS with excels in some areas like%0a%3c security and correctness, this guide could be of some use to people that want%0a%3c to experimenting and deploy secure applications for everyday usage. A basic%0a%3c knowledge of OpenBSD, shell and Common Lisp will boost the process to build%0a%3c and better understand the concept. For those who don't know Common Lisp we%0a%3c suggest to read those books: [BARSKI2010]_ and [SEIBEL2005]_.%0a%3c %0a%3c !!Other resources%0a%3c %0a%3c Online official documentation and info sources from:%0a%3c %0a%3c * FAQ manual `%3chttps://www.openbsd.org/faq/index.html>`_%0a%3c * man pages: `%3chttps://man.openbsd.org>`_%0a%3c * Mailing list `%3chttps://www.openbsd.org/mail.html>`_%0a%3c * #OpenBSD IRC channel on Libera Chat `%3circ.libera.chat>`_%0a%3c * #lisp IRC channel on Libera Chat `%3circ.libera.chat>`_%0a%3c * #lisp IRC channel on IRC Now `%3circ.bsdforall.org>`_%0a%3c %0a%3c !!Legally speaking...%0a%3c %0a%3c We referenced to the BSD 3 clauses license for this work and the related code.%0a%3c %0a%3c .. comment: -*- mode: rst-mode; coding: utf-8; electric-indent-mode: t; -*-%0a%3c %0a%3c %0a%3c !Getting Started%0a%3c %0a%3c !!The installation process%0a%3c %0a%3c We refer to a running and functional installation of OpenBSD 7.4 for amd64%0a%3c platform even if the majority of the ideas can be used on othe platform too%0a%3c as sparc64 and arm64. First of all we open a terminal window: OpenBSD uses%0a%3c csh as standard shell interpreter, int this guide we prefer the bash shell%0a%3c so, as root, we can give the command:%0a%3c %0a%3c %0a%3c @@$ doas pkg_add -v bash@@%0a%3c %0a%3c %0a%3c After the installation we can add to the system the Stell Bank Common Lisp%0a%3c interpreter/compiler - sbcl with:%0a%3c %0a%3c %0a%3c @@$ doas pkg_add -v sbcl@@%0a%3c %0a%3c %0a%3c !!Configuration for sbcl%0a%3c %0a%3c As installed, sbcl is already working with its default configuration which are%0a%3c specified in its \*features\* global variable, for example, let's run sbcl:%0a%3c %0a%3c @@$ sbcl@@%0a%3c %0a%3c the system responds with:%0a%3c %0a%3c @@This is SBCL 2.3.8.openbsd.sbcl-2.3.8, an implementation of ANSI Common Lisp.@@\\%0a%3c @@More information about SBCL is available at %3chttp://www.sbcl.org/>.@@\\%0a%3c @@SBCL is free software, provided as is, with absolutely no warranty.@@\\%0a%3c @@It is mostly in the public domain; some portions are provided under@@\\%0a%3c @@BSD-style licenses. See the CREDITS and COPYING files in the@@\\%0a%3c @@distribution for more information.@@\\%0a%3c @@*@@\\%0a%3c %0a%3c Or with a very similar message, informing us that the interpreter is ready and%0a%3c it is waiting for a command to be entered at the REPL [#]_ prompt \*. At this point%0a%3c we would like to see some configurations/characteristics of this particular%0a%3c version of the interpreter, so we enter:%0a%3c %0a%3c .. [#]%0a%3c %0a%3c REPL stands for Read, Eval and Print Loop: a way to interact with a user.%0a%3c At first the informations entered after the prompt are read, then evaluated%0a%3c by the sbcl interpreter and a result is always printed/returned back to the%0a%3c user. The cycle continues with the interpreter waiting for the user to enter%0a%3c informations again.%0a%3c %0a%3c %0a%3c .. code::%0a%3c %0a%3c * *features*%0a%3c (:ARENA-ALLOCATOR :X86-64 :GENCGC :64-BIT :ANSI-CL :BSD :COMMON-LISP :ELF%0a%3c :IEEE-FLOATING-POINT :LITTLE-ENDIAN :OPENBSD :PACKAGE-LOCAL-NICKNAMES%0a%3c :SB-CORE-COMPRESSION :SB-LDB :SB-PACKAGE-LOCKS :SB-THREAD :SB-UNICODE :SBCL%0a%3c :UNIX)%0a%3c *%0a%3c %0a%3c %0a%3c Installing quicklisp%0a%3c --------------------%0a%3c %0a%3c Let's quit the interpreter and continue installing other software that we will%0a%3c use to make a Common Lisp development environment, the editor. We choose emacs%0a%3c which is, among other things, programmed largely in Lisp, it has inside it a%0a%3c Common Lisp interpreter which is used to perform operation on text as well as%0a%3c configurations:%0a%3c %0a%3c .. code:: shell%0a%3c %0a%3c $ doas pkg_add -v emacs%0a%3c %0a%3c %0a%3c At this point the installer can ask us to choose among different version of%0a%3c emacs. Choose the one is best with your desktop environment or, if you like%0a%3c install the version with no desktop support at all, you can still use it from%0a%3c the console or terminal with no great difference from the desktop version.%0a%3c Also emacs has got is own configuration which is accessible with the program%0a%3c interface or modifying a file in the home directory. We will see how to%0a%3c achieve that in the following paragraph, by now let's install the quicklisp%0a%3c common lisp library system. This is a completely written in Common Lisp%0a%3c piece of software, which make the user capable of handling projects related%0a%3c to Common Lisp itself, we will use it to let our software use already written%0a%3c libraries. To install quicklisp we have to download the quicklisp installer%0a%3c from the site `%3chttps://beta.quicklisp.org>`_ . We use curl to do that, so:%0a%3c %0a%3c %0a%3c .. code:: shell%0a%3c %0a%3c $ doas pkg_add -v curl%0a%3c %0a%3c %0a%3c proceed to retrieve the quicklisp library:%0a%3c %0a%3c .. code:: shell%0a%3c %0a%3c curl -O https://beta.quicklisp.org/quicklisp.lisp%0a%3c %0a%3c %0a%3c and the library file signature to check its authenticity:%0a%3c %0a%3c %0a%3c .. code:: shell%0a%3c %0a%3c $ curl -O https://beta.quicklisp.org/quicklisp.lisp.asc%0a%3c %0a%3c %0a%3c then we check the signature of the downloaded file:%0a%3c %0a%3c %0a%3c .. code:: shell%0a%3c %0a%3c $ gpg --verify quicklisp.lisp.asc quicklisp.lisp%0a%3c gpg: Signature made Sat Feb 1 09:25:28 2014 EST using RSA key ID 028B5FF7%0a%3c gpg: Good signature from "Quicklisp Release Signing Key "%0a%3c %0a%3c %0a%3c The downloaded file is then usable to install the quicklisp library manager. At%0a%3c This point we face two main choices: we can install the library manager only%0a%3c for the user or system-wide. We assume for now that the installation is%0a%3c limited to one user, so we can proceed as follows:%0a%3c %0a%3c %0a%3c .. code::%0a%3c %0a%3c $ sbcl --load quicklisp.lisp%0a%3c This is SBCL 2.3.8.openbsd.sbcl-2.3.8, an implementation of ANSI Common Lisp.%0a%3c More information about SBCL is available at %3chttp://www.sbcl.org/>.%0a%3c %0a%3c SBCL is free software, provided as is, with absolutely no warranty.%0a%3c It is mostly in the public domain; some portions are provided under%0a%3c BSD-style licenses. See the CREDITS and COPYING files in the%0a%3c distribution for more information.%0a%3c %0a%3c ==== quicklisp quickstart 2015-01-28 loaded ====%0a%3c %0a%3c To continue with installation, evaluate: (quicklisp-quickstart:install)%0a%3c %0a%3c For installation options, evaluate: (quicklisp-quickstart:help)%0a%3c %0a%3c *%0a%3c %0a%3c .. raw:: pdf%0a%3c %0a%3c PageBreak%0a%3c %0a%3c %0a%3c At this point we can proceed to install the library:%0a%3c %0a%3c .. code::%0a%3c %0a%3c * (quicklisp-quickstart:install)%0a%3c ...%0a%3c ==== quicklisp installed ====%0a%3c %0a%3c To load a system, use: (ql:quickload "system-name")%0a%3c %0a%3c To find systems, use: (ql:system-apropos "term")%0a%3c %0a%3c To load Quicklisp every time you start Lisp, use: (ql:add-to-init-file)%0a%3c %0a%3c For more information, see http://www.quicklisp.org/beta/%0a%3c %0a%3c T%0a%3c *%0a%3c %0a%3c %0a%3c To use the library with the sbcl REPL we must instruct sbcl itself to load a%0a%3c configuration batch file called .sbclrc which resides in the user home.%0a%3c Quicklisp can do that for us as stated in the message above, in fact let's%0a%3c issue the form in the REPL:%0a%3c %0a%3c %0a%3c .. code::%0a%3c %0a%3c * (ql:add-to-init-file)%0a%3c I will append the following lines to #P"/home/user/.sbclrc":%0a%3c %0a%3c ;;; The following lines added by ql:add-to-init-file:%0a%3c #-quicklisp%0a%3c (let ((quicklisp-init #P"/home/user/quicklisp/setup.lisp"))%0a%3c (when (probe-file quicklisp-init)%0a%3c (load quicklisp-init)))%0a%3c %0a%3c Press Enter to continue.%0a%3c %0a%3c #P"/home/user/.sbclrc"%0a%3c * (quit)%0a%3c %0a%3c To return to the shell prompt, we can check that the following code is then%0a%3c written in the .sbclrc file:%0a%3c %0a%3c .. code::%0a%3c %0a%3c $ cat ~/.sbclrc%0a%3c ;;; The following lines added by ql:add-to-init-file:%0a%3c #-quicklisp%0a%3c (let ((quicklisp-init #P"/home/user/quicklisp/setup.lisp"))%0a%3c (when (probe-file quicklisp-init)%0a%3c (load quicklisp-init)))%0a%3c %0a%3c %0a%3c .. raw:: pdf%0a%3c %0a%3c PageBreak%0a%3c %0a%3c %0a%3c .sbclrc is the file which is read and evaluated from sbcl before entering the%0a%3c REPL, we can place configuration for sbcl code in there, for example we want%0a%3c sbcl and quicklisp to include our personal Common Lisp projects repository%0a%3c which is, for example, in ~/Development/lisp directory. So we add the%0a%3c following code at the end of .sbclrc:%0a%3c %0a%3c %0a%3c .. code:: common-lisp%0a%3c %0a%3c (defun setup-registry (directory-path)%0a%3c (format t "; adding components under ~A to asdf registry~%25" directory-path)%0a%3c (mapc (lambda (asd-pathname)%0a%3c (pushnew (make-pathname :name nil%0a%3c :type nil%0a%3c :version nil%0a%3c :defaults asd-pathname)%0a%3c asdf:*central-registry*%0a%3c :test #'equal))%0a%3c (directory (merge-pathnames #p"**/*.asd" directory-path))))%0a%3c %0a%3c (setup-registry (merge-pathnames #p"Development/lisp/" (user-homedir-pathname)))%0a%3c %0a%3c %0a%3c Let's see what happens when we launch sbcl:%0a%3c %0a%3c .. code:: shell%0a%3c %0a%3c $ sbcl%0a%3c This is SBCL 2.3.8.openbsd.sbcl-2.3.8, an implementation of ANSI Common Lisp.%0a%3c More information about SBCL is available at %3chttp://www.sbcl.org/>.%0a%3c %0a%3c SBCL is free software, provided as is, with absolutely no warranty.%0a%3c It is mostly in the public domain; some portions are provided under%0a%3c BSD-style licenses. See the CREDITS and COPYING files in the%0a%3c distribution for more information.%0a%3c ; adding components under /home/angel/Development/lisp/ to asdf registry%0a%3c *%0a%3c %0a%3c %0a%3c Now let's check what happened to the \*features\*:%0a%3c %0a%3c .. code:: common-lisp%0a%3c %0a%3c * *features*%0a%3c (:QUICKLISP :ASDF3.3 :ASDF3.2 :ASDF3.1 :ASDF3 :ASDF2 :ASDF :OS-UNIX%0a%3c :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :ARENA-ALLOCATOR :X86-64 :GENCGC :64-BIT%0a%3c :ANSI-CL :BSD :COMMON-LISP :ELF :IEEE-FLOATING-POINT :LITTLE-ENDIAN :OPENBSD%0a%3c :PACKAGE-LOCAL-NICKNAMES :SB-CORE-COMPRESSION :SB-LDB :SB-PACKAGE-LOCKS%0a%3c :SB-THREAD :SB-UNICODE :SBCL :UNIX)%0a%3c *%0a%3c %0a%3c %0a%3c .. raw:: pdf%0a%3c %0a%3c PageBreak%0a%3c %0a%3c %0a%3c Configuration for emacs%0a%3c -----------------------%0a%3c %0a%3c Quicklisp library added more features to the basic sbcl behaviour especially%0a%3c related to ASDF. Now let's configure emacs to allow us to have a REPL inside%0a%3c a window:%0a%3c %0a%3c .. code::%0a%3c %0a%3c $ sbcl%0a%3c ...%0a%3c * (ql:quickload :quicklisp-slime-helper)%0a%3c To load "quicklisp-slime-helper":%0a%3c Load 1 ASDF system:%0a%3c quicklisp-slime-helper%0a%3c ; Loading "quicklisp-slime-helper"%0a%3c [package swank-loader]............................%0a%3c [package quicklisp-slime-helper]%0a%3c slime-helper.el installed in "/home/user/quicklisp/slime-helper.el"%0a%3c %0a%3c To use, add this to your ~/.emacs:%0a%3c %0a%3c (load (expand-file-name "/home/user/quicklisp/slime-helper.el"))%0a%3c ;; Replace "sbcl" with the path to your implementation%0a%3c (setq inferior-lisp-program "sbcl")%0a%3c %0a%3c %0a%3c (:QUICKLISP-SLIME-HELPER)%0a%3c *%0a%3c %0a%3c %0a%3c To add the code showed by the message before we shall open ~/.emacs which is%0a%3c in turn the configuration file for emacs and add the lines:%0a%3c %0a%3c %0a%3c .. code:: common-lisp%0a%3c %0a%3c (load (expand-file-name "/home/user/quicklisp/slime-helper.el"))%0a%3c ;; Replace "sbcl" with the path to your implementation%0a%3c (setq inferior-lisp-program "sbcl")%0a%3c %0a%3c %0a%3c once the .emacs file is edited we can launch emacs and we have the window:%0a%3c %0a%3c %0a%3c .. image:: ./images/emacs-001.png%0a%3c %0a%3c %0a%3c we start SLIME by pressing the key Alt and x on the keyboard, emacs will let us%0a%3c enter a command:%0a%3c %0a%3c %0a%3c .. image:: ./images/emacs-002.png%0a%3c %0a%3c %0a%3c we enter the command "slime" at the "M-x" prompt:%0a%3c %0a%3c %0a%3c .. image:: ./images/emacs-003.png%0a%3c %0a%3c %0a%3c and press the enter key on the keyboard. The SLIME REPL appears:%0a%3c %0a%3c %0a%3c .. image:: ./images/emacs-004.png%0a%3c %0a%3c %0a%3c Let's see what are the \*features\* now using the SLIME REPL:%0a%3c %0a%3c %0a%3c .. image:: ./images/emacs-005.png%0a%3c %0a%3c %0a%3c We can try to load a package "antik", and then:%0a%3c %0a%3c %0a%3c .. code:: common-lisp%0a%3c %0a%3c CL-USER> (ql:quickload :antik)%0a%3c ...%0a%3c (:ANTIK)%0a%3c CL-USER>%0a%3c %0a%3c %0a%3c antik provides some useful constants and standard quantities handling in%0a%3c scientific calculations such as:%0a%3c %0a%3c %0a%3c .. code:: common-lisp%0a%3c %0a%3c CL-USER> antik:+days-per-month+%0a%3c 30%0a%3c CL-USER>%0a%3c %0a%3c %0a%3c .. raw:: pdf%0a%3c %0a%3c PageBreak%0a%3c %0a%3c %0a%3c .. raw:: pdf%0a%3c %0a%3c OddPageBreak%0a%3c %0a%3c %0a%3c .. comment: End of file.%0a---%0a> Copyright (C) 2023 Angelo Rossi %3cangelo.rossi.homelab@gmail.com>%0a> %0a> Redistribution and use in source and binary forms, with or without%0a> modification, are permitted provided that the following conditions%0a> are met:%0a> %0a> 1. Redistributions of source code must retain the above copyright%0a> notice, this list of conditions and the following disclaimer.%0a> 2. Redistributions in binary form must reproduce the above copyright%0a> notice, this list of conditions and the following disclaimer in the%0a> documentation and/or other materials provided with the distribution.%0a> 3. Neither the name of the University nor the names of its contributors%0a> may be used to endorse or promote products derived from this software%0a> without specific prior written permission.%0a> %0a> THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND%0a> ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE%0a> IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE%0a> ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE%0a> FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL%0a> DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS%0a> OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)%0a> HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT%0a> LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY%0a> OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF%0a> SUCH DAMAGE.%0a> %0a
73 host:1700844753=93.45.233.109
74 author:1700843694=Posterdati
75 diff:1700843694:1700843694:=1,45d0%0a%3c !Common Lisp on OpenBSD%0a%3c %0a%3c ---------------------------------%0a%3c !! With a simple Hunchentoot example%0a%3c ---------------------------------%0a%3c %0a%3c || border=1 width=50%25 class="sortable simpletable"%0a%3c ||!Revision||!Description||!Name ||%0a%3c ||0.0.1 ||This table ||Angelo Rossi %3cangelo.rossi.homelab@gmail.com>||%0a%3c || || || ||%0a%3c %0a%3c %0a%3c !!!Preface to this Edition%0a%3c %0a%3c This is a lone work by Angelo Rossi %3cangelo.rossi.homelab@gmail.com>%0a%3c %0a%3c !!!License Information%0a%3c %0a%3c Copyright (C) 2023 Angelo Rossi %3cangelo.rossi.homelab@gmail.com>%0a%3c %0a%3c Redistribution and use in source and binary forms, with or without%0a%3c modification, are permitted provided that the following conditions%0a%3c are met:%0a%3c %0a%3c 1. Redistributions of source code must retain the above copyright%0a%3c notice, this list of conditions and the following disclaimer.%0a%3c 2. Redistributions in binary form must reproduce the above copyright%0a%3c notice, this list of conditions and the following disclaimer in the%0a%3c documentation and/or other materials provided with the distribution.%0a%3c 3. Neither the name of the University nor the names of its contributors%0a%3c may be used to endorse or promote products derived from this software%0a%3c without specific prior written permission.%0a%3c %0a%3c THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND%0a%3c ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE%0a%3c IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE%0a%3c ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE%0a%3c FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL%0a%3c DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS%0a%3c OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)%0a%3c HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT%0a%3c LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY%0a%3c OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF%0a%3c SUCH DAMAGE.%0a%3c %0a
76 host:1700843694=93.45.233.109