Connect to localhost instead of failing.
[doldaconnect.git] / lib / guile / autodl
CommitLineData
d3372da9 1#!/usr/bin/guile -s
2!#
3
4(use-modules (dolcon ui))
5(use-modules (ice-9 pretty-print))
6
7(define sr '())
8(define lastsearch 0)
9(define info-searcheta 0)
10(define info-numavail 0)
11(define info-numreal 0)
12(define info-numtotal 0)
13(define lastparse 0)
14(define srchid -1)
15(define session '())
16(define trans '())
17(define dpeers '())
18(define lastdl 0)
19
20(define (logf msg)
21 (write-line msg (current-output-port))
22 (catch 'system-error (lambda ()
23 (fsync (current-output-port)))
24 (lambda (key . err) #f))
25 )
26
27(define (make-getopt opts optdesc)
28 (let ((arg opts) (curpos 0) (rest '()))
29 (lambda ()
30 (if (eq? arg '()) rest
31 (let ((ret #f))
32 (while (not ret)
33 (if (= curpos 0)
34 (if (eq? (string-ref (car arg) 0) #\-)
35 (set! curpos 1)
36 (begin
37 (set! rest (append rest (list (car arg))))
38 (set! arg (cdr arg))
39 (if (eq? arg '())
40 (set! ret #t)))))
41 (if (> curpos 0)
42 (if (< curpos (string-length (car arg)))
43 (begin (set! ret (string-ref (car arg) curpos)) (set! curpos (+ curpos 1)))
44 (begin (set! curpos 0) (set! arg (cdr arg)) (if (eq? arg '()) (set! ret #t))))))
45 (if (eq? ret #t) rest
46 (let ((opt (string-index optdesc ret)))
47 (if (eq? opt #f) (throw 'illegal-option ret)
48 (if (and (< opt (- (string-length optdesc) 1)) (eq? (string-ref optdesc (+ opt 1)) #\:))
49 (let ((ret
50 (cons ret (let ((optarg
51 (if (< curpos (string-length (car arg)))
52 (substring (car arg) curpos)
53 (begin (set! arg (cdr arg)) (if (eq? arg '()) (throw 'requires-argument ret)) (car arg)))))
54 (set! arg (cdr arg)) optarg))))
55 (set! curpos 0)
56 ret)
57 (list ret))))))))))
58
59(define (ftime)
60 (let ((ctime (gettimeofday)))
61 (+ (car ctime) (/ (cdr ctime) 1000000))))
62
63(define (wanttosearch)
64 (> (- (current-time) lastsearch)
d30cc4bc 65 (if (eq? (cdr (assoc 'search-mode session)) 'wait)
66 7200
67 (if (> (length trans) 0) 300 60)))
d3372da9 68 )
69
70(define defspeed '())
71(let ((matchlist (list
72 (cons (make-regexp "^[][{}() ]*BBB" regexp/icase) 100000))))
73 (set! defspeed
74 (lambda (sr)
75 (catch 'ret
76 (lambda ()
77 (for-each (lambda (o)
78 (if (regexp-exec (car o) (cadr (cdr (assoc 'peer sr))))
79 (throw 'ret (cdr o))))
80 matchlist)
81 15000)
82 (lambda (sig ret)
83 ret))
84 )))
85
86(define (sr-less? sr1 sr2)
87 (let ((s1 (if (cdr (assoc 'speed sr1)) (cdr (assoc 'speed sr1)) (defspeed sr1)))
88 (s2 (if (cdr (assoc 'speed sr2)) (cdr (assoc 'speed sr2)) (defspeed sr2))))
89 (if (= s1 s2)
90 (< (cdr (assoc 'resptime sr1)) (cdr (assoc 'resptime sr2)))
91 (> s1 s2)))
92 )
93
94(define (srg-less? g1 g2)
95 (or (> (length (cdr g1)) (length (cdr g2)))
96 (and (= (length (cdr g1)) (length (cdr g2)))
97 (> (car g1) (car g2))))
98 )
99
100(define (gettrbysize size)
101 (catch 'ret
102 (lambda ()
103 (for-each (lambda (o)
104 (if (= (cdr (assoc 'size (cdr o))) size)
105 (throw 'ret (cdr o))))
106 trans)
107 #f)
108 (lambda (sig ret)
109 ret))
110 )
111
112(define (download sr)
113 (let ((resp #f))
114 (let ((args (list "download"
115 (car (cdr (assoc 'peer sr)))
116 (cadr (cdr (assoc 'peer sr)))
117 (cdr (assoc 'filename sr))
118 (cdr (assoc 'size sr)))))
3b0de0fd 119 (let ((hash (assoc 'hash sr)))
120 (if (and hash (not (equal? (cdr hash) ""))) (set! args (append args (list "hash" (cdr hash))))))
d3372da9 121 (let ((tag (assoc 'tag session)))
122 (if tag (set! args (append args (list "tag" (cdr tag))))))
123 (let ((uarg (assoc 'uarg session)))
124 (if uarg (set! args (append args (list "user" (cdr uarg))))))
e838f46b 125 (let ((xargs (assoc 'xargs session)))
126 (if xargs (for-each (lambda (o)
127 (set! args (append args (list (car o) (cdr o)))))
128 (cdr xargs))))
d3372da9 129 (set! resp (apply dc-ecmd-assert 200 args)))
130 (let ((id (car (dc-intresp resp))))
131 (set! trans
132 (cons (cons id (list (assoc 'size sr)
133 (assoc 'peer sr)
134 (assoc 'filename sr)
135 (assoc 'resptime sr)
136 '(curpos . 0)
137 '(state . wait)
138 '(curspeed . #f)
139 '(lastpos . 0)
140 (cons 'id id)
141 (cons 'lasttime (current-time))
142 (cons 'lastprog (current-time))))
143 trans))
144 (logf (string-append "downloading "
145 (cdr (assoc 'filename sr))
146 " from "
147 (cadr (cdr (assoc 'peer sr)))
148 ", "
149 (number->string (cdr (assoc 'size sr)))
150 " bytes (id "
151 (number->string id)
152 ", "
153 (number->string (cdr (assoc 'slots sr)))
154 " slots), timing out in "
155 (number->string (max 10 (* (cdr (assoc 'resptime sr)) 2)))
156 " seconds"))))
157 (set! lastdl (current-time))
158 )
159
160(define (disablepeer peer)
161 (let ((newglist '()) (numrem 0))
162 (for-each (lambda (g)
163 (let ((newlist '()))
164 (for-each (lambda (o)
165 (if (not (equal? (cdr (assoc 'peer o)) peer))
166 (set! newlist (cons o newlist))
167 (set! numrem (+ numrem 1))))
168 (cdr g))
169 (if (not (eq? newlist '()))
170 (set! newglist (cons (cons (car g) (sort newlist sr-less?)) newglist)))))
171 sr)
172 (set! sr (sort newglist srg-less?))
173 (logf (string-append "disabled " (cadr peer) " and removed " (number->string numrem) " search results")))
174 (let* ((dpa (assoc peer dpeers)) (dp (and (pair? dpa) (cdr dpa))))
175 (if dp
176 (set-cdr! (assoc 'time dp) (current-time))
177 (set! dpeers (cons (cons peer (list (cons 'time (current-time))
178 (cons 'peer peer)))
179 dpeers))))
180 )
181
182(define (checktrans)
183 (let ((time (current-time)))
184 (for-each (lambda (o)
185 (if (and (memq (cdr (assoc 'state (cdr o))) '(wait hs))
186 (> (- time (cdr (assoc 'lastprog (cdr o)))) (max 10 (* (cdr (assoc 'resptime (cdr o))) 2))))
187 (begin (logf (string-append "transfer " (number->string (car o)) " timing out"))
188 (dc-ecmd-assert 200 "cancel" (car o))
189 (disablepeer (cdr (assoc 'peer (cdr o))))
ecd6e23d 190 (set! trans (assq-remove! trans (car o)))
191 (write-info-file)))
d3372da9 192 (if (and (eq? (cdr (assoc 'state (cdr o))) 'main)
193 (> (- time (cdr (assoc 'lastprog (cdr o)))) 60))
194 (begin (logf (string-append "transfer " (number->string (car o)) " seems to have stalled"))
195 (dc-ecmd-assert 200 "cancel" (car o))
ecd6e23d 196 (set! trans (assq-remove! trans (car o)))
197 (write-info-file)))
d3372da9 198 (if (and (eq? (cdr (assoc 'state (cdr o))) 'main)
199 (> (- (cdr (assoc 'lastprog (cdr o))) (cdr (assoc 'lasttime (cdr o)))) 20))
200 (begin (set-cdr! (assoc 'curspeed (cdr o))
201 (/ (- (cdr (assoc 'curpos (cdr o))) (cdr (assoc 'lastpos (cdr o))))
202 (- (cdr (assoc 'lastprog (cdr o))) (cdr (assoc 'lasttime (cdr o))))))
203 (set-cdr! (assoc 'lastpos (cdr o)) (cdr (assoc 'curpos (cdr o))))
ecd6e23d 204 (set-cdr! (assoc 'lasttime (cdr o)) (cdr (assoc 'lastprog (cdr o))))
205 (write-info-file))))
d3372da9 206 trans))
207 )
208
209(define (write-info-file)
210 (if (assoc 'info-file session)
211 (let ((op (open-output-file (cdr (assoc 'info-file session)))))
d576878b 212 (pretty-print (list (cons 'numdl (length trans))
213 (cons 'lastdl lastdl)
214 (cons 'availsr info-numavail)
215 (cons 'realsr info-numreal)
216 (cons 'totalsr info-numtotal)
217 (cons 'lastsrch lastsearch)
218 (cons 'srcheta info-searcheta)
219 (cons 'srchmode (cdr (assoc 'search-mode session))))
220 op)
d3372da9 221 (close-port op))))
222
223(define (parseresults)
224 (logf (string-append "entering parseresults with "
225 (number->string
226 (apply + (map (lambda (o) (length (cdr o))) sr)))
227 " results in "
228 (number->string (length sr))
229 " sizes"))
230 (let ((retval #t) (numreal 0) (numtotal 0) (numavail 0))
231 (catch 'ret
232 (lambda ()
233 (and (eq? sr '()) (throw 'ret #f))
234 (let ((numrem 0) (countrem 0) (newglist '()))
235 (for-each (lambda (g)
236 (let ((newlist '()))
237 (for-each (lambda (o)
238 (if (< (- (current-time) (cdr (assoc 'recvtime o))) 300)
239 (set! newlist (cons o newlist))
240 (set! countrem (+ countrem 1))))
241 (cdr g))
242 (if (> (length newlist) 0)
243 (set! newglist (cons (cons (car g) (sort newlist sr-less?)) newglist))
244 (set! numrem (+ numrem 1)))))
245 sr)
246 (set! sr (sort newglist srg-less?))
247 (if (> countrem 0)
248 (logf (string-append "removed " (number->string countrem) " time-outed results and " (number->string numrem) " entire sizes"))))
249 (let ((numrem 0) (newlist '()))
250 (for-each (lambda (o)
251 (if (> (- (current-time) (cdr (assoc 'time o))) 1800)
252 (set! numrem (+ numrem 1))
253 (set! newlist (cons o newlist))))
254 dpeers)
255 (set! dpeers newlist)
256 (logf (string-append "re-enabled " (number->string numrem) " disabled users")))
257 (let ((numrem 0) (countrem 0) (newglist '()))
258 (for-each (lambda (g)
259 (let ((newlist '()))
260 (for-each (lambda (o)
261 (if (not (assoc (cdr (assoc 'peer o)) dpeers))
262 (set! newlist (cons o newlist))
263 (set! countrem (+ countrem 1))))
264 (cdr g))
265 (if (> (length newlist) 0)
266 (set! newglist (cons (cons (car g) (sort newlist sr-less?)) newglist))
267 (set! numrem (+ numrem 1)))))
268 sr)
269 (set! sr (sort newglist srg-less?))
270 (if (> countrem 0)
271 (logf (string-append "removed " (number->string countrem) " results with disabled peers and " (number->string numrem) " entire sizes"))))
272 (and (eq? sr '()) (throw 'ret #f))
273 (set! numtotal (apply + (map (lambda (o) (length (cdr o))) sr)))
274 (let* ((maxsize (apply max (map (lambda (o) (length (cdr o))) sr)))
275 (minsize (/ maxsize 3)))
276 (let ((numrem 0) (countrem 0))
277 (for-each (lambda (o) (if (< (length (cdr o)) minsize)
278 (begin (set! countrem (+ countrem (length (cdr o))))
279 (set! numrem (+ numrem 1)))))
280 sr)
281 (if (> countrem 0)
282 (logf (string-append "will disregard " (number->string countrem) " results from " (number->string numrem) " sizes due to popularity lack")))
283 (set! numreal (- numtotal countrem)))
284 (let ((numrem 0) (numrrem 0))
285 (for-each (lambda (g)
286 (for-each (lambda (o)
287 (if (< (cdr (assoc 'slots o)) 1)
288 (begin (set! numrem (+ numrem 1))
289 (if (>= (length (cdr g)) minsize)
290 (set! numrrem (+ numrrem 1))))))
291 (cdr g)))
292 sr)
293 (if (> numrem 0)
294 (logf (string-append (number->string numrem) " results had no slots")))
295 (set! numavail (- numreal numrrem)))
296 (for-each (lambda (g)
297 (if (>= (length (cdr g)) minsize)
298 (catch 'found
299 (lambda ()
300 (for-each (lambda (o)
301 (and (> (cdr (assoc 'slots o)) 0)
302 (throw 'found o)))
303 (cdr g)))
304 (lambda (sig sr)
305 (let ((tr (gettrbysize (cdr (assoc 'size sr)))))
306 (if (not tr)
307 (if (< (length trans) (cdr (assoc 'maxtrans session)))
308 (download sr))
309 (if (and (cdr (assoc 'curspeed tr))
310 (not (equal? (cdr (assoc 'peer sr)) (cdr (assoc 'peer tr))))
311 (> (- (or (cdr (assoc 'speed sr)) (defspeed sr)) (cdr (assoc 'curspeed tr))) 10000))
312 (begin (logf (string-append "abandoning transfer "
313 (number->string (cdr (assoc 'id tr)))
314 " for possible faster sender"))
315 (dc-ecmd-assert 200 "cancel" (cdr (assoc 'id tr)))
316 (set! trans (assq-remove! trans (cdr (assoc 'id tr))))
317 (download sr)))))))))
318 sr)
319 )
320 )
321 (lambda (sig ret)
322 (set! retval ret)
323 ))
324 (set! info-numavail numavail)
325 (set! info-numreal numreal)
326 (set! info-numtotal numtotal)
ecd6e23d 327 (write-info-file)
d3372da9 328 retval)
329 )
330
3b0de0fd 331(define (handlesr filename fnet peer size slots resptime hash)
2bb57f49 332 (if (eq? (cdr (assoc 'search-mode session)) 'wait)
333 (begin (set-cdr! (assoc 'search-mode session) 'normal)
334 (logf "reverting to normal mode")))
d3372da9 335 (let ((cl (or (assoc size sr)
336 (let ((newp (cons size '()))) (set! sr (append sr (list newp))) newp)))
337 (newsr (list
338 (cons 'filename filename)
339 (cons 'peer (list fnet peer))
340 (cons 'size size)
341 (cons 'slots slots)
342 (cons 'resptime resptime)
343 (cons 'speed (getspeed peer))
3b0de0fd 344 (cons 'hash hash)
d3372da9 345 (cons 'recvtime (current-time))
346 (cons 'dis #f)))
347 (newlist '()))
348 (for-each (lambda (o) (if (not (and (equal? (cdr (assoc 'filename o)) filename)
349 (equal? (cdr (assoc 'peer o)) (list fnet peer))))
350 (set! newlist (cons o newlist))))
351 (cdr cl))
352 (set-cdr! cl (sort (cons newsr newlist) sr-less?))
353 )
354 )
355
356; XXX: Redefine to go through the server, once that is implemented
357(define (getspeed username)
358 (catch 'system-error
359 (lambda ()
360 (let* ((port (open-input-file (string-append (getenv "HOME") "/dc/users/" username))) (avg 0) (numdls (string->number (read-line port))) (max (string->number (read-line port))) (numents (string->number (read-line port))))
361 (do ((i 0 (+ i 1))) ((= i numents) (close-port port) (/ avg numents)) (set! avg (+ avg (string->number (read-line port)))))
362 ))
363 (lambda args
364 #f
365 )
366 )
367 )
368
369(define (validate-session session)
370 (catch 'wrong-type-arg
371 (lambda ()
372 (and
373 (assoc 'sexpr session)
374 (assoc 'prio session)
375 (assoc 'maxtrans session)
376 #t
377 )
378 )
379 (lambda (key . args)
380 (display "Session data is not an a-list\n" (current-error-port))
381 #f)
382 )
383 )
384
385(define (autodl-main args)
aa82fda0 386 (let ((dc-server #f) (done #f) (retval 0) (filterexit ""))
e838f46b 387 (let ((getopt (make-getopt (cdr args) "whs:S:e:p:t:a:I:E:x:")) (arg #f))
d3372da9 388 (do ((arg (getopt) (getopt))) ((not (and (pair? arg) (char? (car arg)))) (set! args arg))
389 (cond ((eq? (car arg) #\h)
390 (begin (display "usage: autodl [-s server] -S sessfile\n" (current-error-port))
d30cc4bc 391 (display " autodl [-w] [-s server] -e search-expression [-p prio] [-t tag] [-a userarg]\n" (current-error-port))
d3372da9 392 (display " autodl [-s server]\n" (current-error-port))
393 (display " autodl -h\n" (current-error-port))
394 (exit 0)))
395 ((eq? (car arg) #\s)
396 (set! dc-server (cdr arg)))
397 ((eq? (car arg) #\S)
398 (let ((port (open-file (cdr arg)))) (set! session (read port)) (close-port port)))
399 ((eq? (car arg) #\p)
400 (let ((c (assoc 'prio session)))
401 (if c (set-cdr! c (cdr arg))
402 (set! session (cons (cons 'prio (cdr arg)) session)))))
403 ((eq? (car arg) #\t)
404 (let ((c (assoc 'tag session)))
405 (if c (set-cdr! c (cdr arg))
406 (set! session (cons (cons 'tag (cdr arg)) session)))))
407 ((eq? (car arg) #\a)
408 (let ((c (assoc 'uarg session)))
409 (if c (set-cdr! c (cdr arg))
410 (set! session (cons (cons 'uarg (cdr arg)) session)))))
411 ((eq? (car arg) #\I)
412 (let ((c (assoc 'info-file session)))
413 (if c (set-cdr! c (cdr arg))
414 (set! session (cons (cons 'info-file (cdr arg)) session)))))
aa82fda0 415 ((eq? (car arg) #\E)
416 (let ((c (assoc 'estat-file session)))
417 (if c (set-cdr! c (cdr arg))
418 (set! session (cons (cons 'estat-file (cdr arg)) session)))))
d3372da9 419 ((eq? (car arg) #\e)
420 (set! session (cons (cons 'sexpr (dc-lexsexpr (cdr arg))) session)))
d30cc4bc 421 ((eq? (car arg) #\w)
422 (set! session (cons '(search-mode . wait) session)))
e838f46b 423 ((eq? (car arg) #\x)
424 (let* ((c (assoc 'xargs session)) (p (string-index (cdr arg) #\=))
425 (recons (cons (substring (cdr arg) 0 p) (substring (cdr arg) (1+ p)))))
426 (if c (set-cdr! c (cons recons (cdr c)))
427 (set! session (cons (cons 'xargs (list recons)) session)))))
d3372da9 428 )
429 )
430 )
431 (if (eq? session '()) (begin (if (isatty? (current-input-port)) (display "Enter session data (s-expr):\n" (current-error-port))) (set! session (read))))
432 (if (not (assoc 'prio session))
433 (set! session (cons '(prio . 10) session)))
434 (if (not (assoc 'maxtrans session))
435 (set! session (cons '(maxtrans . 1) session)))
d30cc4bc 436 (if (not (assoc 'search-mode session))
53acfa81 437 (set! session (cons '(search-mode . normal) session)))
d3372da9 438 (if (not (validate-session session)) (begin (display "Invalid session!\n" (current-error-port)) (exit 1)))
439 (if (not dc-server) (set! dc-server (getenv "DCSERVER")))
440 (if (not dc-server) (set! dc-server "localhost"))
441 (catch 'system-error
442 (lambda ()
443 (dc-c&l #t dc-server #t))
444 (lambda (key . args)
445 (logf (string-append "could not connect to server: " (apply format #f (cadr args) (caddr args))))
446 (exit 2)))
c6a77cc5 447 (dc-ecmd-assert 200 "notify" "trans:act" "on" "trans:prog" "on" "srch:act" "on")
d3372da9 448 (for-each (lambda (sig) (sigaction sig (lambda (sig) (throw 'sig sig)))) (list SIGINT SIGTERM SIGHUP))
449 (catch 'sig
450 (lambda ()
451 (while #t
452 (if (and (not (= lastsearch -1)) (wanttosearch))
453 (begin
454 (if (not (= srchid -1))
455 (dc-ecmd "cansrch" srchid))
456 (let* ((resp (apply dc-ecmd-assert (append (list '(200 501 509) "search" "prio" (number->string (cdr (assoc 'prio session))) "all") (cdr (assoc 'sexpr session)))))
457 (ires (dc-intresp resp))
458 (eres (dc-extract resp)))
459 (case (cdr (assoc 'code eres))
460 ((200)
461 (begin (set! srchid (car ires))
462 (logf (string-append "search scheduled in " (number->string (cadr ires)) " seconds (id " (number->string srchid) ")"))
463 (set! info-searcheta (+ (current-time) (cadr ires)))
ecd6e23d 464 (set! lastsearch -1)
465 (write-info-file)))
d3372da9 466 ((501)
467 (begin (set! srchid -1)
468 (logf (string-append "no fnetnodes available to search on"))
469 (set! lastsearch (current-time))))
470 ((509)
471 (begin (logf "illegal search expression")
472 (set! done #t)
473 (set! retval 3)
474 (throw 'sig 0)))))))
475 (checktrans)
476 (if (> (- (current-time) lastparse) 20)
477 (begin (parseresults)
478 (set! lastparse (current-time))))
d3372da9 479 (dc-select 10000)
480 (while (let ((resp (dc-getresp)))
481 (if resp
482 (begin
483 (let* ((er (dc-extract resp)) (code (cdr (assoc 'code er))) (cmd (cdr (assoc 'cmd er))))
484 (cond
485 ((equal? cmd ".notify")
486 (case code
487 ((611) ; Transfer state change
488 (let ((ires (dc-intresp resp)) (tr #f))
489 (if (and ires (assoc (car ires) trans))
490 (begin (set! tr (cdr (assoc (car ires) trans)))
491 (set-cdr! (assoc 'state tr)
492 (cdr (assoc (cadr ires) '((0 . wait) (1 . hs) (2 . main) (3 . done)))))
493 (set-cdr! (assoc 'lastprog tr) (current-time))))))
494 ((614) ; Transfer error
495 (let ((ires (dc-intresp resp)))
496 (if (and ires (assoc (car ires) trans))
497 (begin (logf (string-append "transfer " (number->string (car ires)) " encountered error " (number->string (cadr ires))))
498 (dc-ecmd-assert 200 "cancel" (car ires))
499 (let ((tr (cdr (assoc (car ires) trans))))
500 (disablepeer (cdr (assoc 'peer tr))))
501 (set! trans (assq-remove! trans (car ires)))))))
502 ((615) ; Transfer progress
503 (let ((ires (dc-intresp resp)) (tr #f))
504 (if (and ires (assoc (car ires) trans))
505 (begin (set! tr (cdr (assoc (car ires) trans)))
506 (set-cdr! (assoc 'curpos tr) (cadr ires))
507 (set-cdr! (assoc 'lastprog tr) (current-time))))))
508 ((617) ; Transfer destroyed
509 (let* ((ires (dc-intresp resp)) (tr (and ires (assoc (car ires) trans))))
510 (if tr
511 (begin (if (eq? (cdr (assoc 'state (cdr tr))) 'done)
2fc2772d 512 (begin (logf (string-append "transfer " (number->string (car ires)) " done (" (cadr ires) ")"))
d3372da9 513 (set! trans (assq-remove! trans (car ires)))
514 (set! done #t)
2fc2772d 515 (set! filterexit (cadr ires))
d3372da9 516 (throw 'sig 0))
517 (begin (logf (string-append "transfer " (number->string (car ires)) " disappeared"))
518 (set! trans (assq-remove! trans (car ires)))))))))
519 ((620) ; Search rescheduled
520 (let ((ires (dc-intresp resp)))
521 (if (and ires (= (car ires) srchid))
522 (begin (set! info-searcheta (+ (current-time) (cadr ires)))
d30cc4bc 523 (logf (string-append "search rescheduled to T+" (number->string (cadr ires))))
524 (write-info-file)))))
d3372da9 525 ((621) ; Search committed
526 (let ((ires (dc-intresp resp)))
527 (if (and ires (= (car ires) srchid))
528 (begin (logf "search committed")
529 (set! info-searcheta 0)
d30cc4bc 530 (set! lastsearch (current-time))
531 (write-info-file)))))
d3372da9 532 ((622) ; Search result
533 (let ((ires (list->vector (dc-intresp resp))))
3b0de0fd 534 (if (and ires (= (vector-ref ires 0) srchid)) (apply handlesr (map (lambda (n) (vector-ref ires n)) '(1 2 3 4 5 7 8))))))
d3372da9 535
536 )
537 )
538
539 )
540 )
541 #t)
542 #f)
543 )
544 #t
545 )
546 )
547 )
548 (lambda (key sig)
549 (logf (string-append "interrupted by signal " (number->string sig)))
550 (if (not done)
551 (set! retval 1)))
552 )
553 (logf "quitting...")
554 (catch 'sig
555 (lambda ()
556 (if (dc-connected)
557 (begin (for-each (lambda (o)
558 (dc-qcmd (list "cancel" (car o))))
559 trans)
560 (if (assoc 'info-file session)
561 (catch 'system-error
562 (lambda ()
563 (delete-file (cdr (assoc 'info-file session))))
564 (lambda (key . args) #t)))
565 (if (and done (assoc 'tag session))
566 (dc-qcmd (list "filtercmd" "rmtag" (cdr (assoc 'tag session)))))
567 (if (not (= srchid -1))
568 (dc-qcmd (list "cansrch" srchid)))
569 (dc-qcmd '("quit"))
570 (while (dc-connected) (dc-select))
571 )))
572 (lambda (key sig)
573 (logf "forcing quit")))
aa82fda0 574 (if (assoc 'estat-file session)
575 (let ((op (open-output-file (cdr (assoc 'estat-file session)))))
fc068ee7 576 (display filterexit op)
aa82fda0 577 (newline op)
578 (close-port op)))
d3372da9 579 (exit retval)
580 )
581 )
582
583(setlocale LC_ALL "")
584(autodl-main (command-line))