aboutsummaryrefslogtreecommitdiff
path: root/gnu/services/ldap.scm
blob: 49a33fac0863ab35ee1445568525a47eeba63dcb (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2018, 2019, 2022 Ricardo Wurmus <rekado@elephly.net>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of thye GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu services ldap)
  #:use-module (gnu packages admin)
  #:use-module (gnu packages openldap)
  #:use-module (gnu services)
  #:use-module (gnu services configuration)
  #:use-module (gnu services shepherd)
  #:use-module (gnu system shadow)
  #:use-module (guix gexp)
  #:use-module (srfi srfi-1)
  #:use-module (ice-9 match)
  #:use-module (ice-9 string-fun)
  #:export (directory-server-service-type
            directory-server-shepherd-service

            directory-server-instance-configuration
            slapd-configuration
            backend-configuration))

(define (uglify-field-name name)
  (let ((str (string-map (match-lambda
                           (#\- #\_)
                           (chr chr))
                         (symbol->string name))))
    (if (string-suffix? "?" str)
        (substring str 0 (1- (string-length str)))
        str)))
(define (serialize-field field-name val)
  (format #t "~a = ~a\n" (uglify-field-name field-name) val))
(define serialize-string serialize-field)
(define-maybe string)
(define (serialize-boolean field-name val)
  (serialize-field field-name (if val "True" "False")))
(define (serialize-number field-name val)
  (serialize-field field-name (number->string val)))


(define-configuration slapd-configuration
  (instance-name
   (string "localhost")
   "Sets the name of the instance.  You can refer to this value in other
parameters of this INF file using the \"{instance_name}\" variable.  Note that
this name cannot be changed after the installation!")
  (user
   (string "dirsrv")
   "Sets the user name the ns-slapd process will use after the service
started.")
  (group
   (string "dirsrv")
   "Sets the group name the ns-slapd process will use after the service
started.")
  (port
   (number 389)
   "Sets the TCP port the instance uses for LDAP connections.")
  (secure-port
   (number 636)
   "Sets the TCP port the instance uses for TLS-secured LDAP
connections (LDAPS).")
  (root-dn
   (string "cn=Directory Manager")
   "Sets the Distinquished Name (DN) of the administrator account for this
instance.")
  (root-password
   (string "{invalid}YOU-SHOULD-CHANGE-THIS")
   "Sets the password of the account specified in the \"root-dn\" parameter.
You can either set this parameter to a plain text password dscreate hashes
during the installation or to a \"{algorithm}hash\" string generated by the
pwdhash utility.  Note that setting a plain text password can be a security
risk if unprivileged users can read this INF file!")
  (self-sign-cert
   (boolean #t)
   "Sets whether the setup creates a self-signed certificate and enables TLS
encryption during the installation.  This is not suitable for production, but
it enables administrators to use TLS right after the installation.  You can
replace the self-signed certificate with a certificate issued by a certificate
authority.")
  (self-sign-cert-valid-months
   (number 24)
   "Set the number of months the issued self-signed certificate will be valid.")
  (backup-dir
   (string "/var/lib/dirsrv/slapd-{instance_name}/bak")
   "Set the backup directory of the instance.")
  (cert-dir
   (string "/etc/dirsrv/slapd-{instance_name}")
   "Sets the directory of the instance's Network Security Services (NSS)
database.")
  (config-dir
   (string "/etc/dirsrv/slapd-{instance_name}")
   "Sets the configuration directory of the instance.")
  (db-dir
   (string "/var/lib/dirsrv/slapd-{instance_name}/db")
   "Sets the database directory of the instance.")
  (initconfig-dir
   (string "/etc/dirsrv/registry")
   "Sets the directory of the operating system's rc configuration directory.")
  (ldif-dir
   (string "/var/lib/dirsrv/slapd-{instance_name}/ldif")
   "Sets the LDIF export and import directory of the instance.")
  (lock-dir
   (string "/var/lock/dirsrv/slapd-{instance_name}")
   "Sets the lock directory of the instance.")
  (log-dir
   (string "/var/log/dirsrv/slapd-{instance_name}")
   "Sets the log directory of the instance.")
  (run-dir
   (string "/run/dirsrv")
   "Sets PID directory of the instance.")
  (schema-dir
   (string "/etc/dirsrv/slapd-{instance_name}/schema")
   "Sets schema directory of the instance.")
  (tmp-dir
   (string "/tmp")
   "Sets the temporary directory of the instance."))

(define (serialize-slapd-configuration field-name val)
  #t)


(define-configuration backend-userroot-configuration
  (create-suffix-entry?
   (boolean #false)
   "Set this parameter to #true to create a generic root node entry for the
suffix in the database.")
  (require-index?
   (boolean #false)
   "Set this parameter to #true to refuse unindexed searches in this
database.")
  (sample-entries
   (string "no")
   "Set this parameter to \"yes\" to add latest version of sample entries to
this database.  Or, use \"001003006\" to use the 1.3.6 version sample entries.
Use this option, for example, to create a database for testing purposes.")
  (suffix
   maybe-string
   "Sets the root suffix stored in this database.  If you do not set the
suffix attribute the install process will not create the backend/suffix.  You
can also create multiple backends/suffixes by duplicating this section."))

(define (serialize-backend-userroot-configuration field-name val)
  #t)


(define-configuration directory-server-instance-configuration
  (package
    (file-like 389-ds-base)
    "The 389-ds-base package.")
  ;; General settings
  (config-version
   (number 2)
   "Sets the format version of the configuration file.  To use the INF file
with dscreate, this parameter must be 2.")
  (full-machine-name
   (string "localhost")
   "Sets the fully qualified hostname (FQDN) of this system.")
  (selinux
   (boolean #false)
   "Enables SELinux detection and integration during the installation of this
instance.  If set to #T, dscreate auto-detects whether SELinux is enabled.")
  (strict-host-checking
   (boolean #t)
   "Sets whether the server verifies the forward and reverse record set in the
\"full-machine-name\" parameter.  When installing this instance with GSSAPI
authentication behind a load balancer, set this parameter to #F.")
  (systemd
   (boolean #false)
   "Enables systemd platform features.  If set to #T, dscreate auto-detects
whether systemd is installed.")
  (slapd
   (slapd-configuration (slapd-configuration))
   "Configuration of slapd.")
  (backend-userroot
   (backend-userroot-configuration (backend-userroot-configuration))
   "Configuration of the userroot backend."))

(define (serialize-directory-server-instance-configuration x)
  (format #t "[general]\n")
  (serialize-configuration
   x
   (filter (lambda (field)
             (not (member (configuration-field-name field)
                          '(package slapd backend-userroot))))
           directory-server-instance-configuration-fields))
  ;; Do not start instance while running dscreate.  Do this later with
  ;; shepherd.
  (format #t "start = False\n")
  (format #t "\n[slapd]\n")
  (serialize-configuration
   (directory-server-instance-configuration-slapd x)
   slapd-configuration-fields)
  (format #t "\n[backend-userroot]\n")
  (serialize-configuration
   (directory-server-instance-configuration-backend-userroot x)
   backend-userroot-configuration-fields))

(define (directory-server-instance-config-file config)
  "Return an LDAP directory server instance configuration file."
  (let* ((slapd   (directory-server-instance-configuration-slapd config))
         (instance-name (slapd-configuration-instance-name slapd)))
    (plain-file
     (string-append "dirsrv-" instance-name ".inf")
     (with-output-to-string
       (lambda ()
         (serialize-directory-server-instance-configuration config))))))

(define (directory-server-shepherd-service config)
  "Return a shepherd service for an LDAP directory server with CONFIG."
  (let* ((389-ds-base (directory-server-instance-configuration-package config))
         (slapd       (directory-server-instance-configuration-slapd config))
         (instance-name
          (slapd-configuration-instance-name slapd)))
    (list (shepherd-service
           (documentation "Run an 389 directory server instance.")
           (provision (list (symbol-append 'directory-server-
                                           (string->symbol instance-name))))
           (requirement '())
           (start #~(make-forkexec-constructor
                     (list #$(file-append 389-ds-base "/sbin/dsctl")
                           #$instance-name "start")
                     #:pid-file
                     (string-append
                      #$(slapd-configuration-run-dir slapd)
                      "/slapd-" #$instance-name ".pid")))
           (stop #~(make-kill-destructor))))))

(define (directory-server-accounts config)
  (let* ((slapd (directory-server-instance-configuration-slapd config))
         (user (slapd-configuration-user slapd))
         (group (slapd-configuration-group slapd)))
    (list (user-group
           (name group)
           (system? #true))
          (user-account
           (name user)
           (group group)
           (system? #true)
           (comment "System user for the 389 directory server")
           (home-directory "/var/empty")
           (shell (file-append shadow "/sbin/nologin"))))))

(define (directory-server-activation config)
  (let* ((389-ds-base (directory-server-instance-configuration-package config))
         (config-file (directory-server-instance-config-file config))
         (slapd (directory-server-instance-configuration-slapd config))
         (instance-name (slapd-configuration-instance-name slapd))
         (user (slapd-configuration-user slapd))
         (group (slapd-configuration-group slapd))
         (instantiate (lambda (proc)
                        (string-replace-substring
                         (proc slapd) "{instance_name}" instance-name)))
         (config-dir (instantiate slapd-configuration-config-dir))
         (all-dirs (delete-duplicates
                    (map (compose dirname instantiate)
                         (list slapd-configuration-backup-dir
                               slapd-configuration-cert-dir
                               slapd-configuration-db-dir
                               slapd-configuration-ldif-dir
                               slapd-configuration-lock-dir
                               slapd-configuration-log-dir
                               slapd-configuration-run-dir
                               slapd-configuration-schema-dir)))))
    ;; 389-ds-base doesn't let us update an instance configuration, so bail
    ;; out when the configuration directory already exists.
    #~(begin
        (use-modules (ice-9 match)
                     (guix build utils))
        (if (file-exists? #$config-dir)
            (format #t
                    "directory-server: Instance configuration for `~a' already exists.  Skipping.\n"
                    #$instance-name)
            (let ((owner (getpwnam #$user)))
              (for-each (lambda (dir)
                          (mkdir-p dir)
                          (chown dir (passwd:uid owner) (passwd:gid owner)))
                        (sort '#$all-dirs string<=))
              (system* #$(file-append 389-ds-base "/sbin/dscreate")
                       "from-file" #$config-file))))))

(define directory-server-service-type
  (service-type (name 'directory-server)
                (extensions
                 (list (service-extension shepherd-root-service-type
                                          directory-server-shepherd-service)
                       (service-extension activation-service-type
                                          directory-server-activation)
                       (service-extension account-service-type
                                          directory-server-accounts)))
                (default-value (directory-server-instance-configuration))
                (description
                 "Run a directory server instance.")))

(define (generate-directory-server-documentation)
  (generate-documentation
    `((directory-server-instance-configuration
       ,directory-server-instance-configuration-fields
       (slapd slapd-configuration)
       (backend-userroot backend-userroot-configuration))
      (slapd-configuration ,slapd-configuration-fields)
      (backend-userroot-configuration
       ,backend-userroot-configuration-fields))
    'directory-server-instance-configuration))
prescheme/1.3/#Invoking-the-Pre_002dScheme-compiler (with-directory-excursion "ps-compiler" (let ((version #$(package-version this-package)) (port (open-pipe* OPEN_WRITE "scheme48"))) (format port (string-join '(",batch" ",config ,load ../scheme/prescheme/interface.scm" ",config ,load ../scheme/prescheme/package-defs.scm" ",exec ,load load-ps-compiler.scm" ",in prescheme-compiler prescheme-compiler" ",user (define prescheme-compiler ##)" ",dump ../prescheme.image \"(Pre-Scheme ~a)\"" ",exit") "\n" 'suffix) version) (close-pipe port))))) (replace 'install (lambda _ (let* ((s48-version #$(package-version scheme48)) (bin-dir (string-append #$output "/bin")) (lib-dir (string-append #$output "/lib/scheme48-" s48-version)) (pkgconf-dir (string-append #$output "/lib/pkgconfig")) (share-dir (string-append #$output "/share/scheme48-" s48-version)) (include-dir (string-append #$output "/include"))) ;; Install Pre-Scheme compiler image (install-file "prescheme" bin-dir) (install-file "prescheme.image" lib-dir) ;; Install Pre-Scheme config, headers, and lib (install-file "prescheme.pc" pkgconf-dir) (install-file "c/prescheme.h" include-dir) (install-file "c/prescheme-io.h" include-dir) (install-file "c/libprescheme.a" lib-dir) ;; Install Pre-Scheme sources (copy-recursively "scheme/prescheme" (string-append share-dir "/prescheme")) (copy-recursively "ps-compiler" (string-append share-dir "/ps-compiler")) ;; Remove files specific to building the Scheme 48 VM (for-each (lambda (file) (delete-file (string-append share-dir "/" file))) '("ps-compiler/compile-bibop-gc-32.scm" "ps-compiler/compile-bibop-gc-64.scm" "ps-compiler/compile-gc.scm" "ps-compiler/compile-twospace-gc-32.scm" "ps-compiler/compile-twospace-gc-64.scm" "ps-compiler/compile-vm-no-gc-32.scm" "ps-compiler/compile-vm-no-gc-64.scm")))))))) (propagated-inputs (list scheme48)) (home-page "http://s48.org/") (synopsis "Pre-Scheme compiler from Scheme 48") (description "Pre-Scheme is a statically compilable dialect of Scheme, used to implement the Scheme 48 virtual machine. Scheme 48 ships with a Pre-Scheme to C compiler written in Scheme, and a runtime library which allows Pre-Scheme code to run as Scheme.") (license bsd-3))) (define-public gambit-c (package (name "gambit-c") (version "4.9.5") (source (origin (method url-fetch) (uri (string-append "http://www.gambitscheme.org/" version "/gambit-v" (string-map (lambda (c) (if (char=? c #\.) #\_ c)) version) ".tgz")) (sha256 (base32 "1p61z1rp0ya4i61mq3hzmr67r3xbvi9h058cf9ci2yqfbzdzi3p2")))) (build-system gnu-build-system) (arguments '(#:configure-flags ;; According to the ./configure script, this makes the build slower and ;; use >= 1 GB memory, but makes Gambit much faster. '("--enable-single-host"))) (home-page "http://www.gambitscheme.org/") (synopsis "Efficient Scheme interpreter and compiler") (description "Gambit consists of two main programs: gsi, the Gambit Scheme interpreter, and gsc, the Gambit Scheme compiler. The interpreter contains the complete execution and debugging environment. The compiler is the interpreter extended with the capability of generating executable files. The compiler can produce standalone executables or compiled modules which can be loaded at run time. Interpreted code and compiled code can be freely mixed.") ;; Dual license. (license (list lgpl2.1+ asl2.0)))) (define-public chibi-scheme (package (name "chibi-scheme") (version "0.11") (home-page "https://github.com/ashinn/chibi-scheme") (source (origin (method git-fetch) (uri (git-reference (url home-page) (commit version))) (file-name (git-file-name name version)) (sha256 (base32 "02zq35hdbi03rmmamx6ml4ihsigdl4mmbf6d9ysazv8ciiln5v4b")))) (build-system gnu-build-system) (arguments `(#:phases (modify-phases %standard-phases (delete 'configure)) ; no configure script #:make-flags (let ((out (assoc-ref %outputs "out"))) (list (string-append "PREFIX=" out) (string-append "CC=" ,(cc-for-target)) (string-append "LDFLAGS=-Wl,-rpath=" out "/lib"))) #:test-target "test")) (synopsis "Small embeddable Scheme implementation") (description "Chibi-Scheme is a very small library with no external dependencies intended for use as an extension and scripting language in C programs. In addition to support for lightweight VM-based threads, each VM itself runs in an isolated heap allowing multiple VMs to run simultaneously in different OS threads.") (license bsd-3))) (define-public sicp (let ((commit "bda03f79d6e2e8899ac2b5ca6a3732210e290a79") (revision "3")) (package (name "sicp") (version (git-version "20180718" revision commit)) (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/sarabander/sicp") (commit commit))) (sha256 (base32 "0mng7qrj2dvssyffr9ycnf4a5k0kadp4dslq7mc5bhzq1qxyjs2w")) (file-name (git-file-name name version)))) (build-system copy-build-system) (native-inputs (list gzip texinfo)) (arguments (list #:install-plan ''(("html" "share/doc/sicp/") ("sicp.info" "share/info/")) #:phases #~(modify-phases %standard-phases (add-after 'unpack 'remove-obsolete-commands (lambda _ ;; Reported upstream: ;; https://github.com/sarabander/sicp/issues/46. (substitute* "sicp-pocket.texi" (("@setshortcontentsaftertitlepage") "")))) (add-before 'install 'build (lambda _ (invoke "makeinfo" "--no-split" "--output=sicp.info" "sicp-pocket.texi")))))) (home-page "https://sarabander.github.io/sicp") (synopsis "Structure and Interpretation of Computer Programs") (description "Structure and Interpretation of Computer Programs (SICP) is a textbook aiming to teach the principles of computer programming. Using Scheme, a dialect of the Lisp programming language, the book explains core computer science concepts such as abstraction in programming, metalinguistic abstraction, recursion, interpreters, and modular programming.") (license cc-by-sa4.0)))) (define-public scheme48-rx (let* ((commit "dd9037f6f9ea01019390614f6b126b7dd293798d") (revision "2")) (package (name "scheme48-rx") (version (string-append "0.0.0-" revision "." (string-take commit 7))) (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/scheme/rx") (commit commit))) (sha256 (base32 "1bvriavxw5kf2izjbil3999vr983vkk2xplfpinafr86m40b2cci")) (file-name (string-append name "-" version "-checkout")))) (build-system trivial-build-system) (arguments `(#:modules ((guix build utils)) #:builder (begin (use-modules (guix build utils)) (let ((share (string-append %output "/share/scheme48-" ,(package-version scheme48) "/rx"))) (chdir (assoc-ref %build-inputs "source")) (mkdir-p share) (copy-recursively "." share) #t)))) (native-inputs `(("source" ,source) ("scheme48" ,scheme48))) (home-page "https://github.com/scheme/rx/") (synopsis "SRE String pattern-matching library for scheme48") (description "String pattern-matching library for scheme48 based on the SRE regular-expression notation.") (license bsd-3)))) (define-public slib (package (name "slib") (version "3c1") (source (origin (method url-fetch) (uri (string-append "http://groups.csail.mit.edu/mac/ftpdir/scm/slib-" version ".zip")) (sha256 (base32 "10f7l0fmd0xzs6kc2cwqjrx7msdn0fsd918r459xyc05wscfpy62")))) (build-system gnu-build-system) (arguments `(#:tests? #f ; There is no check target. #:phases (modify-phases %standard-phases (add-after 'install 'remove-bin-share (lambda* (#:key inputs outputs #:allow-other-keys) (delete-file-recursively (string-append (assoc-ref outputs "out") "/bin")) #t)) (replace 'configure (lambda* (#:key inputs outputs #:allow-other-keys) (invoke "./configure" (string-append "--prefix=" (assoc-ref outputs "out")))))))) (native-inputs (list unzip texinfo)) (home-page "https://people.csail.mit.edu/jaffer/SLIB.html") (synopsis "Compatibility and utility library for Scheme") (description "SLIB is a portable Scheme library providing compatibility and utility functions for all standard Scheme implementations.") (license (non-copyleft "http://people.csail.mit.edu/jaffer/SLIB_COPYING.txt" "Or see COPYING in the distribution.")))) (define-public scm (package (name "scm") (version "5f4") (source (origin (method url-fetch) (uri (string-append "http://groups.csail.mit.edu/mac/ftpdir/scm/scm-" version ".zip")) (sha256 (base32 "17i6shvh2caqmksm7z130f9fz0qinaxg7xz9yadv904xh3znshnk")))) (build-system gnu-build-system) (arguments `(#:phases (modify-phases %standard-phases (replace 'configure (lambda* (#:key inputs outputs #:allow-other-keys) (invoke "./configure" (string-append "--prefix=" (assoc-ref outputs "out"))))) (add-before 'build 'pre-build (lambda* (#:key inputs #:allow-other-keys) (substitute* "Makefile" (("ginstall-info") "install-info")) #t)) (replace 'build (lambda* (#:key inputs outputs #:allow-other-keys) (setenv "SCHEME_LIBRARY_PATH" (search-input-directory inputs "lib/slib/")) (invoke "make" "scmlit" "CC=gcc") (invoke "make" "all"))) (add-after 'install 'post-install (lambda* (#:key inputs outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (req (string-append out "/lib/scm/require.scm"))) (delete-file req) (format (open req (logior O_WRONLY O_CREAT)) "(define (library-vicinity) ~s)\n" (search-input-directory inputs "lib/slib/")) ;; We must generate the slibcat file. (invoke (string-append out "/bin/scm") "-br" "new-catalog"))))))) (inputs (list slib)) (native-inputs (list unzip texinfo)) (home-page "https://people.csail.mit.edu/jaffer/SCM") (synopsis "Scheme implementation conforming to R5RS and IEEE P1178") (description "GNU SCM is an implementation of Scheme. This implementation includes Hobbit, a Scheme-to-C compiler, which can generate C files whose binaries can be dynamically or statically linked with a SCM executable.") (license lgpl3+))) (define-public tinyscheme (package (name "tinyscheme") (version "1.42") (source (origin (method url-fetch) (uri (string-append "mirror://sourceforge/" name "/" name "/" name "-" version "/" name "-" version ".zip")) (sha256 (base32 "0rik3qnxqd8wjlazx8rw996pfzkjjg60v6hcbpcqzi7rgml8q4n8")))) (build-system gnu-build-system) (native-inputs (list unzip)) (arguments `(#:phases (modify-phases %standard-phases (replace 'unpack (lambda* (#:key source #:allow-other-keys) (invoke "unzip" source) (chdir (string-append ,name "-" ,version)) #t)) (add-after 'unpack 'set-scm-directory ;; Hard-code ‘our’ init.scm instead of looking in the current ;; working directory, so invoking ‘scheme’ just works. (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (scm (string-append out "/share/" ,name))) (substitute* "scheme.c" (("init.scm" all) (string-append scm "/" all))) #t))) (delete 'configure) ; no configure script (replace 'install ;; There's no ‘install’ target. Install files manually. (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (bin (string-append out "/bin")) (doc (string-append out "/share/doc/" ,name "-" ,version)) (include (string-append out "/include")) (lib (string-append out "/lib")) (scm (string-append out "/share/" ,name))) (install-file "scheme" bin) (install-file "Manual.txt" doc) (install-file "scheme.h" include) (install-file "libtinyscheme.so" lib) (install-file "init.scm" scm) #t)))) #:tests? #f)) ; no tests (home-page "https://tinyscheme.sourceforge.net/") (synopsis "Light-weight interpreter for the Scheme programming language") (description "TinyScheme is a light-weight Scheme interpreter that implements as large a subset of R5RS as was possible without getting very large and complicated. It's meant to be used as an embedded scripting interpreter for other programs. As such, it does not offer an Integrated Development Environment (@dfn{IDE}) or extensive toolkits, although it does sport a small (and optional) top-level loop. As an embedded interpreter, it allows multiple interpreter states to coexist in the same program, without any interference between them. Foreign functions in C can be added and values can be defined in the Scheme environment. Being quite a small program, it is easy to comprehend, get to grips with, and use.") (license bsd-3))) ; there are no licence headers (define-public tr7 (package (name "tr7") (version "1.0.10") (source (origin (method git-fetch) (uri (git-reference (url "https://gitlab.com/jobol/tr7") (commit (string-append "v" version)))) (sha256 (base32 "0n77fkm5kcv2pmwbw5fl8r00aarw8da8gkd9d1ki5fn9kbl4fyk2")) (file-name (git-file-name name version)))) (build-system gnu-build-system) (outputs '("out" "doc")) (arguments (list #:phases #~(modify-phases %standard-phases (replace 'configure (lambda _ (substitute* "Makefile" (("PREFIX = /usr/local") (string-append "PREFIX=" #$output)) (("ALL = \\$\\(LIBSTA\\) \\$\\(TR7I\\) tags") "ALL = $(LIBSTA) $(TR7I)")))) (replace 'build (lambda _ (setenv "CC" #$(cc-for-target)) (invoke "make"))) (replace 'check (lambda* (#:key tests? #:allow-other-keys) (when tests? (invoke "make" "test")))) (replace 'install (lambda _ (let* ((share (string-append #$output "/share")) (doc (string-append #$output:doc "/share/doc/")) (bin (string-append #$output "/bin")) (lib (string-append #$output "/lib/")) (tr7 (string-append share "/tr7")) (libs (string-append tr7 "/libs"))) (for-each mkdir-p (list tr7 libs bin lib doc)) (copy-file "tr7i" (string-append bin "/tr7i")) (copy-file "libtr7.a" (string-append lib "/libtr7.a")) (copy-file "r7rs.pdf" (string-append doc "/r7rs.pdf")) (copy-recursively "tr7libs" libs))))))) (home-page "https://gitlab.com/jobol/tr7") (synopsis "Embedded R7RS small Scheme interpreter") (description "TR7 is a lightweight Scheme interpreter that implements the revision R7RS small of scheme programming language. It is meant to be used as an embedded scripting interpreter for other programs. A lot of functionality in TR7 is included conditionally, to allow developers freedom in balancing features and footprint.") (license bsd-0))) (define-public stalin (let ((commit "ed1c9e339c352b7a6fee40bb2a47607c3466f0be")) ;; FIXME: The Stalin "source" contains C code generated by itself: ;; 'stalin-AMD64.c', etc. (package (name "stalin") (version "0.11") (source (origin ;; Use Pearlmutter's upstream branch with AMD64 patches ;; applied. Saves us from including those 20M! patches ;; in Guix. For more info, see: ;; <ftp.ecn.purdue.edu/qobi/stalin-0.11-amd64-patches.tgz> (method git-fetch) (uri (git-reference (url "https://github.com/barak/stalin") (commit commit))) (file-name (string-append name "-" version "-checkout")) (sha256 (base32 "15a5gxj9v7jqlgkg0543gdflw0rbrir7fj5zgifnb33m074wiyhn")) (modules '((guix build utils))) (snippet ;; remove gc libs from build, we have them as input '(begin (delete-file "gc6.8.tar.gz") (delete-file-recursively "benchmarks") (substitute* "build" ((".*gc6.8.*") "") ((" cd \\.\\.") "") ((".*B include/libgc.a") "") ((".*make.*") "")) #t)))) (build-system gnu-build-system) (arguments `(#:make-flags (list "ARCH_OPTS=-freg-struct-return") #:phases (modify-phases %standard-phases (replace 'configure (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (include-out (string-append out "/include"))) (invoke "./build") (for-each (lambda (fname) (install-file fname include-out)) (find-files "include")) (substitute* "makefile" (("\\./include") include-out)) (substitute* "post-make" (("`pwd`") out)) #t))) (delete 'check) (replace 'install (lambda* (#:key outputs #:allow-other-keys) (let ((out (assoc-ref outputs "out"))) (install-file "stalin.1" (string-append out "/share/man/man1")) (install-file "stalin" (string-append out "/bin")) #t)))))) (inputs (list libx11)) (propagated-inputs (list libgc)) (supported-systems '("x86_64-linux")) (home-page "https://engineering.purdue.edu/~qobi/papers/fdlcc.pdf") (synopsis "Brutally efficient Scheme compiler") (description "Stalin is an aggressively optimizing whole-program compiler for Scheme that does polyvariant interprocedural flow analysis, flow-directed interprocedural escape analysis, flow-directed lightweight CPS conversion, flow-directed lightweight closure conversion, flow-directed interprocedural lifetime analysis, automatic in-lining, unboxing, and flow-directed program-specific and program-point-specific low-level representation selection and code generation.") (license gpl2+)))) (define-public s9fes (package (name "s9fes") (version "20181205") (source (origin (method url-fetch) (uri (string-append "https://www.t3x.org/s9fes/s9fes-" version ".tgz")) (sha256 (base32 "0ynpl707bc9drwkdpdgvw14bz9zmwd3wffl1k02sxppjl28xm7rf")))) (build-system gnu-build-system) (arguments `(#:make-flags (list (string-append "CC=" ,(cc-for-target)) (string-append "PREFIX=" %output)) #:phases (modify-phases %standard-phases (replace 'install (lambda* (#:key make-flags #:allow-other-keys) (apply invoke "make" "install-all" make-flags)))) #:tests? #f)) ; No check target. (inputs (list ncurses)) (home-page "https://www.t3x.org/s9fes/") (synopsis "Interpreter for R4RS Scheme") (description "Scheme 9 from Empty Space (S9fES) is a mature, portable, and comprehensible public-domain interpreter for R4RS Scheme offering: @itemize @item bignum arithmetics @item decimal-based real number arithmetics @item support for low-level Unix programming @item cursor addressing with Curses @item basic networking procedures @item an integrated online help system @item loads of useful library functions @end itemize") (license public-domain))) (define-public femtolisp (let ((commit "ec7601076a976f845bc05ad6bd3ed5b8cde58a97") (revision "2")) (package (name "femtolisp") (version (string-append "0.0.0-" revision "." (string-take commit 7))) (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/JeffBezanson/femtolisp") (commit commit))) (file-name (string-append name "-" version "-checkout")) (sha256 (base32 "1fcyiqlqn27nd4wxi27km8mhmlzpzzsxzpwsl1bxbmhraq468njw")))) ;; See "utils.h" for supported systems. Upstream bug: ;; https://github.com/JeffBezanson/femtolisp/issues/25 (supported-systems (fold delete %supported-systems '("armhf-linux" "mips64el-linux" "aarch64-linux"))) (build-system gnu-build-system) (arguments `(#:make-flags '("CC=gcc" "release") #:test-target "test" #:phases (modify-phases %standard-phases (delete 'bootstrap) (delete 'configure) ; No configure script (replace 'install ; Makefile has no 'install phase (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (bin (string-append out "/bin"))) (install-file "flisp" bin) #t))) ;; The flisp binary is now available, run bootstrap to ;; generate flisp.boot and afterwards runs make test. (add-after 'install 'bootstrap-gen-and-test (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (bin (string-append out "/bin"))) (invoke "./bootstrap.sh") (install-file "flisp.boot" bin) #t)))))) (synopsis "Scheme-like lisp implementation") (description "@code{femtolisp} is a scheme-like lisp implementation with a simple, elegant Scheme dialect. It is a lisp-1 with lexical scope. The core is 12 builtin special forms and 33 builtin functions.") (home-page "https://github.com/JeffBezanson/femtolisp") (license bsd-3)))) (define-public gauche (package (name "gauche") (version "0.9.15") (home-page "https://practical-scheme.net/gauche/index.html") (source (origin (method url-fetch) (uri (string-append "https://github.com/shirok/Gauche/releases/download/release" (string-replace-substring version "." "_") "/Gauche-" version ".tgz")) (sha256 (base32 "10zpbbikkcpdzk6c52wkckiyhn7nhnqjv2djdzyjr0n8qxxy4hrn")))) (build-system gnu-build-system) (inputs (list libatomic-ops slib zlib)) (native-inputs (list texinfo openssl ; needed for tests pkg-config)) ; needed to find external libatomic-ops (arguments `(#:configure-flags (list (string-append "--with-slib=" (assoc-ref %build-inputs "slib") "/lib/slib")) #:phases (modify-phases %standard-phases (add-after 'unpack 'patch-/bin/sh ;; Needed only for tests. (lambda _ (substitute* '("test/www.scm" "ext/tls/test.scm" "lib/gauche/package/util.scm" "libsrc/gauche/process.scm") (("/bin/sh") (which "sh"))))) (add-after 'build 'build-doc (lambda _ (with-directory-excursion "doc" (invoke "make" "info")))) (add-before 'check 'patch-network-tests ;; Remove net checks. (lambda _ (delete-file "test/net.scm") (invoke "touch" "test/net.scm"))) (add-after 'install 'install-docs (lambda _ (with-directory-excursion "doc" (invoke "make" "install"))))))) (synopsis "Scheme scripting engine") (description "Gauche is a R7RS Scheme scripting engine aiming at being a handy tool that helps programmers and system administrators to write small to large scripts quickly. Quick startup, built-in system interface, native multilingual support are some of the goals. Gauche comes with a package manager/installer @code{gauche-package} which can download, compile, install and list gauche extension packages.") (license bsd-3))) (define-public sbcl-airship-scheme (let ((commit "1862db81dfa67729444916c361f39f9f1c5a2ccd") (revision "0")) (package (name "sbcl-airship-scheme") (version (git-version "0.0.0" revision commit)) (source (origin (method git-fetch) (uri (git-reference (url "https://gitlab.com/mbabich/airship-scheme.git") (commit commit))) (file-name (git-file-name "cl-airship-scheme" version)) (sha256 (base32 "1d1kvrzlx5kcfsn3rn30ww8jihjflpgcka3n3awj2k4f0sq4mplg")))) (build-system asdf-build-system/sbcl) (native-inputs (list sbcl-fiveam)) (inputs (list sbcl-alexandria sbcl-float-features sbcl-trivial-features sbcl-zr-utils)) (synopsis "R7RS Scheme implementation in Common Lisp") (description "This is a R7RS Scheme implementation designed to run within a Common Lisp environment.") (home-page "https://gitlab.com/mbabich/airship-scheme") (license expat)))) (define-public cl-airship-scheme (sbcl-package->cl-source-package sbcl-airship-scheme)) (define-public gerbil (package (name "gerbil") (version "0.18.1") (source (origin (method url-fetch) (uri (string-append "https://github.com/mighty-gerbils/gerbil/releases/download/v" version "/gerbil-v" version ".tar.gz")) (sha256 (base32 "1dff14bzqkq6scyyhnwhc3ky96j6lr84mnghk4da0x6vifw7p0p1")))) (arguments (list #:phases #~(modify-phases %standard-phases (delete 'bootstrap) (add-after 'set-paths 'set-cc (lambda _ (setenv "CC" #$(cc-for-target)))) (add-before 'patch-generated-file-shebangs 'fix-gxi-shebangs (lambda _ ;; Some .ss files refer to gxi using /usr/bin/env gxi ;; and 'patch-generated-file-shebangs can't fix that ;; because gxi has not been compiled yet. ;; We know where gxi is going to end up so we ;; Doctor Who our fix here before the problem ;; happens towards the end of the build.sh script. (let ((abs-srcdir (getcwd))) (for-each (lambda (f) (substitute* f (("#!/usr/bin/env gxi") (string-append "#!" abs-srcdir "/../bin/gxi")))) '("./src/std/web/rack-test.ss" "./src/std/web/fastcgi-test.ss" "./src/std/build.ss" "./src/build/build-libgerbil.ss" "./src/gerbil/test/test-build-static-exe.ss" "./src/gerbil/test/test-build-optimized-static-exe.ss" "./src/gerbil/test/test-build-optimized-exe.ss" "./src/gerbil/test/test-build-exe.ss" "./src/srfi/build.ss" "./src/r7rs-large/build.ss" "./src/misc/rpc-perf/build.ss" "./src/misc/http-perf/build.ss" "./src/misc/scripts/docsnarf.ss" "./src/misc/scripts/docstub.ss" "./src/misc/scripts/docsyms.ss" "./src/tools/gxpkg.ss" "./src/tools/build.ss" "./src/lang/build.ss" "./src/tutorial/kvstore/build.ss" "./src/tutorial/httpd/build.ss" "./src/tutorial/proxy/build.ss" "./src/tutorial/ensemble/build.ss" "./src/tutorial/lang/build.ss"))))) (replace 'build (lambda _ (setenv "HOME" (getcwd)) (invoke ;; The build script needs a tty or it'll crash on an ioctl ;; trying to find the width of the terminal it's running on. ;; Calling in script prevents that. "script" "-qefc" "./build.sh")))) #:tests? #f)) (native-inputs (list gambit-c util-linux)) (propagated-inputs (list gambit-c openssl sqlite zlib)) (build-system gnu-build-system) (synopsis "Meta-dialect of Scheme with post-modern features") (description "Gerbil is an opinionated dialect of Scheme designed for Systems Programming, with a state of the art macro and module system on top of the Gambit runtime. The macro system is based on quote-syntax, and provides the full meta-syntactic tower with a native implementation of syntax-case. It also provides a full-blown module system, similar to PLT Scheme's (sorry, Racket) modules. The main difference from Racket is that Gerbil modules are single instantiation, supporting high performance ahead of time compilation and compiled macros.") (home-page "https://cons.io") (license `(,lgpl2.1 ,asl2.0)))) (define-public emacs-gerbil-mode (package (inherit gerbil) (name "emacs-gerbil-mode") (version "1.0") (build-system emacs-build-system) (arguments (list #:phases #~(modify-phases %standard-phases (add-before 'install 'change-directory (lambda _ (chdir "etc")))))) (synopsis "Emacs major-mode for editing Gerbil code") (description "Gerbil mode provides font-lock, indentation, navigation, and REPL for Gerbil code within Emacs."))) (define-public stklos (package (name "stklos") (version "1.70") (source (origin (method url-fetch) ;; TODO: Unbundle pcre, libgc, and libffi. (uri (string-append "https://stklos.net/download/stklos-" version ".tar.gz")) (sha256 (base32 "1iw3pgycjz3kz3jd1855v2ngf8ib2almpf8v058n1mkj1qd2b88m")))) (build-system gnu-build-system) (arguments (list #:modules `((ice-9 ftw) ,@%default-gnu-modules) #:phases #~(modify-phases %standard-phases (add-before 'configure 'patch-sh-references (lambda* (#:key inputs #:allow-other-keys) (let ((bash (which "bash"))) (substitute* "configure" (("/bin/sh") bash))))) (add-after 'configure 'patch-rm-references (lambda _ (let ((rm (which "rm"))) (substitute* (find-files "." "^Makefile$") (("/bin/rm") rm)))))))) (properties '((release-monitoring-url . "https://stklos.net/download.html"))) (home-page "https://stklos.net") (synopsis "R7RS Scheme with CLOS-like object system") (description "STklos is a free Scheme system mostly compliant with the languages features defined in R7RS small. The aim of this implementation is to be fast as well as light. The implementation is based on an ad-hoc Virtual Machine. STklos can also be compiled as a library and embedded in an application.") (license gpl2+))) (define-public r7rs-small-texinfo (let ((commit "38a703976ea6353e32b52a5187dbdaf77fb2f050") (revision "3")) (package (name "r7rs-small-texinfo") (version (git-version "0.1.0" revision commit)) (home-page "https://codeberg.org/Zipheir/r7rs-small-texinfo/") (source (origin (uri (git-reference (url home-page) (commit commit))) (method git-fetch) (file-name (git-file-name name version)) (sha256 (base32 "1fr02fyhiwd364jkfy1n5w31pq3kx1rl5w634421g05702yb47x3")))) (native-inputs (list bash texinfo)) (inputs '()) (build-system copy-build-system) (arguments (list #:install-plan #~'(("r7rs-small.info" "share/info/")) #:phases #~(modify-phases %standard-phases (add-after 'unpack 'compile-the-files (lambda _ (let* ((source-directory-path (string-append (getcwd) "/doc/r7rs-small")) (build-script-path (string-append source-directory-path "/build.sh")) (info-directory-path (string-append #$output "/share/info"))) (chdir source-directory-path) (system* "bash" build-script-path "info") (mkdir-p info-directory-path) (copy-file (string-append source-directory-path "/r7rs-small.info") (string-append info-directory-path "/r7rs-small.info")))))))) (synopsis "R7RS Small standard of the Scheme programming language in Info format") (description "Revised^7 Report of the Algorithmic Language Scheme adapted to Texinfo format.") (license (non-copyleft "file://COPYING")))))