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
|
;; Copyright 2006-2014, Matthew Welland.
;;
;; This program is made available under the GNU GPL version 2.0 or
;; greater. See the accompanying file COPYING for details.
;;
;; This program is distributed WITHOUT ANY WARRANTY; without even the
;; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
;; PURPOSE.
(require-extension (srfi 18) extras tcp s11n)
(use sqlite3 srfi-1 posix srfi-69 hostinfo dot-locking)
(import (prefix sqlite3 sqlite3:))
(declare (unit portlogger))
;; lsof -i
(define (portlogger:open-db fname)
(let* ((avail (tasks:wait-on-journal fname 5 remove: #t)) ;; wait up to about 10 seconds for the journal to go away
(exists (file-exists? fname))
(db (if avail
(sqlite3:open-database fname)
(begin
(system (conc "rm -f " fname))
(sqlite3:open-database fname))))
(handler (make-busy-timeout 136000))
(canwrite (file-write-access? fname)))
(sqlite3:set-busy-handler! db handler)
(sqlite3:execute db "PRAGMA synchronous = 0;")
(if (not exists)
(sqlite3:execute
db
"CREATE TABLE IF NOT EXISTS ports (
port INTEGER PRIMARY KEY,
state TEXT DEFAULT 'not-used',
fail_count INTEGER DEFAULT 0,
update_time TIMESTAMP DEFAULT (strftime('%s','now')) );"))
db))
(define (portlogger:open-run-close proc . params)
(let* ((fname (conc "/tmp/." (current-user-name) "-portlogger.db"))
(avail (tasks:wait-on-journal fname 10))) ;; wait up to about 10 seconds for the journal to go away
(handle-exceptions
exn
(begin
;; (release-dot-lock fname)
(debug:print 0 "ERROR: portlogger:open-run-close failed. " proc " " params)
(debug:print 0 " message: " ((condition-property-accessor 'exn 'message) exn))
(debug:print 0 "exn=" (condition->list exn))
(print-call-chain))
(let* (;; (lock (obtain-dot-lock fname 2 9 10))
(db (portlogger:open-db fname))
(res (apply proc db params)))
(sqlite3:finalize! db)
;; (release-dot-lock fname)
res))))
|
|
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
>
|
|
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
|
;; Copyright 2006-2014, Matthew Welland.
;;
;; This program is made available under the GNU GPL version 2.0 or
;; greater. See the accompanying file COPYING for details.
;;
;; This program is distributed WITHOUT ANY WARRANTY; without even the
;; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
;; PURPOSE.
(require-extension (srfi 18) extras tcp s11n)
(use sqlite3 srfi-1 posix srfi-69 hostinfo dot-locking z3)
(import (prefix sqlite3 sqlite3:))
(declare (unit portlogger))
(declare (uses db))
;; lsof -i
(define (portlogger:open-db fname)
(let* ((avail (tasks:wait-on-journal fname 5 remove: #t)) ;; wait up to about 10 seconds for the journal to go away
(exists (file-exists? fname))
(db (if avail
(sqlite3:open-database fname)
(begin
(system (conc "rm -f " fname))
(sqlite3:open-database fname))))
(handler (make-busy-timeout 136000))
(canwrite (file-write-access? fname)))
;; (db-init (lambda ()
;; (sqlite3:execute
;; db
;; "CREATE TABLE IF NOT EXISTS ports (
;; port INTEGER PRIMARY KEY,
;; state TEXT DEFAULT 'not-used',
;; fail_count INTEGER DEFAULT 0,
;; update_time TIMESTAMP DEFAULT (strftime('%s','now')) );"))))
(sqlite3:set-busy-handler! db handler)
(db:set-sync db) ;; (sqlite3:execute db "PRAGMA synchronous = 0;")
;; (if (not exists) ;; needed with IF NOT EXISTS?
(sqlite3:execute
db
"CREATE TABLE IF NOT EXISTS ports (
port INTEGER PRIMARY KEY,
state TEXT DEFAULT 'not-used',
fail_count INTEGER DEFAULT 0,
update_time TIMESTAMP DEFAULT (strftime('%s','now')) );")
db))
(define (portlogger:open-run-close proc . params)
(let* ((fname (conc "/tmp/." (current-user-name) "-portlogger.db"))
(avail (tasks:wait-on-journal fname 10))) ;; wait up to about 10 seconds for the journal to go away
(handle-exceptions
exn
(begin
;; (release-dot-lock fname)
(debug:print 0 "ERROR: portlogger:open-run-close failed. " proc " " params)
(debug:print 0 " message: " ((condition-property-accessor 'exn 'message) exn))
(debug:print 0 "exn=" (condition->list exn))
(if (file-exists? fname)(delete-file fname)) ;; brutally get rid of it
(print-call-chain (current-error-port)))
(let* (;; (lock (obtain-dot-lock fname 2 9 10))
(db (portlogger:open-db fname))
(res (apply proc db params)))
(sqlite3:finalize! db)
;; (release-dot-lock fname)
res))))
|
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
(define (portlogger:get-prev-used-port db)
(handle-exceptions
exn
(begin
(debug:print 0 "EXCEPTION: portlogger database probably overloaded or unreadable. If you see this message again remove /tmp/.$USER-portlogger.db")
(debug:print 0 " message: " ((condition-property-accessor 'exn 'message) exn))
(debug:print 0 "exn=" (condition->list exn))
(print-call-chain)
(debug:print 0 "Continuing anyway.")
#f)
(sqlite3:fold-row
(lambda (var curr)
(or curr var curr))
#f
db
|
|
|
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
(define (portlogger:get-prev-used-port db)
(handle-exceptions
exn
(begin
(debug:print 0 "EXCEPTION: portlogger database probably overloaded or unreadable. If you see this message again remove /tmp/.$USER-portlogger.db")
(debug:print 0 " message: " ((condition-property-accessor 'exn 'message) exn))
(debug:print 0 "exn=" (condition->list exn))
(print-call-chain (current-error-port))
(debug:print 0 "Continuing anyway.")
#f)
(sqlite3:fold-row
(lambda (var curr)
(or curr var curr))
#f
db
|
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
(random (- 64000 lowport))))))
(handle-exceptions
exn
(begin
(debug:print 0 "EXCEPTION: portlogger database probably overloaded or unreadable. If you see this message again remove /tmp/.$USER-portlogger.db")
(debug:print 0 " message: " ((condition-property-accessor 'exn 'message) exn))
(debug:print 0 "exn=" (condition->list exn))
(print-call-chain)
(debug:print 0 "Continuing anyway."))
(portlogger:take-port db portnum))
portnum))
;; set port to "released", "failed" etc.
;;
(define (portlogger:set-port db portnum value)
|
|
|
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
(random (- 64000 lowport))))))
(handle-exceptions
exn
(begin
(debug:print 0 "EXCEPTION: portlogger database probably overloaded or unreadable. If you see this message again remove /tmp/.$USER-portlogger.db")
(debug:print 0 " message: " ((condition-property-accessor 'exn 'message) exn))
(debug:print 0 "exn=" (condition->list exn))
(print-call-chain (current-error-port))
(debug:print 0 "Continuing anyway."))
(portlogger:take-port db portnum))
portnum))
;; set port to "released", "failed" etc.
;;
(define (portlogger:set-port db portnum value)
|
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
(handle-exceptions
exn
(begin
(debug:print 0 "EXCEPTION: portlogger database at " dbfname " probably overloaded or unreadable. Try removing it.")
(debug:print 0 " message: " ((condition-property-accessor 'exn 'message) exn))
(print "exn=" (condition->list exn))
(debug:print 0 " status: " ((condition-property-accessor 'sqlite3 'status) exn))
(print-call-chain))
(cond
((> numargs 1) ;; most commands
(case (string->symbol (car args)) ;; commands with two or more params
((take)(portlogger:take-port db (string->number (cadr args))))
((set) (portlogger:set-port db
(string->number (cadr args))
(caddr args))
(caddr args))
((failed)(portlogger:set-failed db (string->number (cadr args))) 'failed)))))))
(sqlite3:finalize! db)
result))
;; (print (apply portlogger:main (cdr (argv))))
|
|
|
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
(handle-exceptions
exn
(begin
(debug:print 0 "EXCEPTION: portlogger database at " dbfname " probably overloaded or unreadable. Try removing it.")
(debug:print 0 " message: " ((condition-property-accessor 'exn 'message) exn))
(print "exn=" (condition->list exn))
(debug:print 0 " status: " ((condition-property-accessor 'sqlite3 'status) exn))
(print-call-chain (current-error-port)))
(cond
((> numargs 1) ;; most commands
(case (string->symbol (car args)) ;; commands with two or more params
((take)(portlogger:take-port db (string->number (cadr args))))
((set) (portlogger:set-port db
(string->number (cadr args))
(caddr args))
(caddr args))
((failed)(portlogger:set-failed db (string->number (cadr args))) 'failed)))))))
(sqlite3:finalize! db)
result))
;; (print (apply portlogger:main (cdr (argv))))
|