Minor changes.
[egate.git] / www / z39util.tcl
1 #
2 # $Id: z39util.tcl,v 1.19 1996/01/09 16:16:49 adam Exp $
3 #
4 proc saveState {} {
5     uplevel #0 {
6     set f [open "tcl.state.${sessionId}" w]
7     foreach var [info globals] {
8         if {$var == "f"} continue
9         if {$var == "sessionId"} continue
10         if {$var == "errorInfo"} continue
11         if {[catch {set names [array names $var]}]} {
12             eval "set v \$${var}"
13             puts $f "set ${var} \{$v\}"
14         } else {
15             foreach n $names {
16                 eval "set v \$${var}(\$n)"
17                 puts $f "set ${var}($n) \{$v\}"
18             }
19             catch {
20                 eval "set v \$${var}"
21                 puts $f "set ${var} \{$v\}"
22             }
23         }
24     }
25     close $f
26     }
27 }
28
29 proc search-response {zz} {
30     global sessionWait
31
32     set status [$zz responseStatus]
33     if {[lindex $status 0] == "NSD"} {
34         $zz nextResultSetPosition 0
35         set code [lindex $status 1]
36         set msg [lindex $status 2]
37         set addinfo [lindex $status 3]
38         displayError "Diagnostic message" \
39                 "$msg: $addinfo<br>\n(error code $code)"
40         set sessionWait -2
41     } else {
42         set sessionWait 1
43     }
44 }
45
46 proc scan-response {zz} {
47     global sessionWait
48
49     set status [$zz scanStatus]
50     if {$status == 6} {
51         displayError "Scan fail" ""
52         set sessionWait -2
53     } else {
54         set sessionWait 1
55     }
56 }
57
58 proc ok-response {} {
59     global sessionWait
60     set sessionWait 1
61 }
62
63 proc fail-response {} {
64     global sessionWait
65     set sessionWait -1
66 }
67
68 proc display-brief {zset no tno} {
69     global env
70     global setNo
71     global sessionId
72
73
74     html {<li>}
75     set type [$zset type $no]
76     if {$type == "SD"} {
77         set err [lindex [$zset diag $no] 1]
78         set add [lindex [$zset diag $no] 2]
79         if {$add != {}} {
80             set add " :${add}"
81         }
82         html "${no} Error ${err}${add} <br>\n"
83         return
84     }
85     if {$type != "DB"} {
86         return
87     }
88     set rtype [$zset recordType $no]
89     if {$rtype == "SUTRS"} {
90         html [join [$zset getSutrs $no]]
91         html "<br>\n"
92         return
93     } 
94     if {![catch {
95         set author [$zset getMarc $no field 100 * a]
96         set title [lindex [$zset getMarc $no field 245 * a] 0]
97         set year [lindex [$zset getMarc $no field 260 * c] 0]
98     } ] } {
99         set p 0
100         foreach a $author {
101             if {$p} {
102                 html ", "
103             }
104             html $a
105             set p 1
106         }
107         if {$p} {
108             html ": "
109         }
110         html {<a href="http:} $env(SCRIPT_NAME) /
111         html $sessionId {/showfull.egw/} $setNo + $tno + $no + full {">}
112         if {[string length $title] == 0} {
113             html {No title}
114         } else {
115             html $title
116         }
117         html {</a>} " <i> ${year} </i>"
118     }
119     html "<br>\n"
120 }
121
122 proc display-raw {zset no tno} {
123     set type [$zset type $no]
124     if {$type == "SD"} {
125         set err [lindex [$zset diag $no] 1]
126         set add [lindex [$zset diag $no] 2]
127         if {$add != {}} {
128             set add " :${add}"
129         }
130         html "<h3>${no}</h3>\n"
131         html "Error ${err}${add} <br>\n"
132         return
133     }
134     if {$type != "DB"} {
135         return
136     }
137     set rtype [$zset recordType $no]
138     if {$rtype == "SUTRS"} {
139         html [join [$zset getSutrs $no]] "<br>\n"
140         return
141     } 
142     if {[catch {set r [$zset getMarc $no line * * *]}]} {
143         html "Unknown record type: $rtype <br>\n"
144         return
145     }
146     foreach line $r {
147         set tag [lindex $line 0]
148         set indicator [lindex $line 1]
149         set fields [lindex $line 2]
150         set l [string length $indicator]
151         html "<tt>$tag "
152         if {$l > 0} {
153             for {set i 0} {$i < $l} {incr i} {
154                 if {[string index $indicator $i] == " "} {
155                     html "-"
156                 } else {
157                     html [string index $tag $i]
158                 }
159             }
160         }
161         html "</tt>"
162         foreach field $fields {
163             set id [lindex $field 0]
164             set data [lindex $field 1]
165             if {$id != ""} {
166                 html " <b>\$$id</b> "
167             }
168             html $data
169         }
170         htmlr {<br>}
171     }
172 }
173
174 proc put-marc-contents {cc} {
175     set ref ""
176     if {[string first :// $cc] > 0} {
177         foreach urltype {gopher http ftp mailto} {
178             if {[string first ${urltype}:// $cc] == 0} {
179                 set ref $urltype
180                 break
181             }
182         }
183     } 
184     if {$ref != ""} {
185         html {<a href="}
186     }
187     html $cc
188     if {$ref != ""} {
189         html {">} $cc {</a>}
190     }
191 }
192
193 proc dl-marc-field {zset no tag id la lb sep} {
194     set n 0
195     set c [$zset getMarc $no field $tag * $id]
196     set len [llength $c]
197     if {$len == 0} {
198         return 0
199     }
200     if {$len > 1 && "x$lb" != "x"} {
201         html "<dt><b>$lb</b>\n<dd>"
202     } else {
203         html "<dt><b>$la</b>\n<dd>"
204     }
205     foreach cc $c {
206         if {$n > 0} {
207             html $sep
208         }
209         put-marc-contents $cc
210         incr n
211     }
212     return $n
213 }
214
215 proc dd-marc-field {zset no tag id start stop} {
216     set n 0
217     set c [$zset getMarc $no field $tag * $id]
218     set len [llength $c]
219     if {$len == 0} {
220         return 0
221     }
222     foreach cc $c {
223         html $start
224         put-marc-contents $cc
225         html $stop
226         incr n
227     }
228     return $n
229 }
230
231 proc dl-marc-field-rec {zset no tag lead start stop startid sep} {
232     set n 0
233     set lines [$zset getMarc $no line $tag * *]
234     foreach line $lines {
235         foreach field [lindex $line 2] {
236             if {$n == 0} {
237                 html "<dt><b>$lead</b>"
238                 html "\n<dd>"
239             }
240             set id [lindex $field 0]
241             if {$id == $startid} {
242                 if {$n > 0} {
243                     html $stop
244                 }
245                 html $start
246                 incr n
247                 html [lindex $field 1]
248             } else {
249                 html $sep
250                 html [lindex $field 1]
251             }
252         }
253     }
254     if {$n > 0} {
255         html $stop
256     }
257 }
258
259 proc display-full {zset no tno} {
260     set type [$zset type $no]
261     if {$type == "SD"} {
262         set err [lindex [$zset diag $no] 1]
263         set add [lindex [$zset diag $no] 2]
264         if {$add != {}} {
265             set add " :${add}"
266         }
267         html "Error ${err}${add} <br>\n"
268         return
269     }
270     if {$type != "DB"} {
271         return
272     }
273     set rtype [$zset recordType $no]
274     if {$rtype == "SUTRS"} {
275         html [join [$zset getSutrs $no]] "<br>\n"
276         return
277     } 
278     if {[catch {set r [$zset getMarc $no line * * *]}]} {
279         html "Unknown record type: $rtype <br>\n"
280         return
281     }
282     html "<dl>\n"
283     set n [dl-marc-field $zset $no 700 a "Author" "Authors" "<br>\n"]
284     if {$n == 0} {
285         set n [dl-marc-field $zset $no 100 a "Author" "Authors" "<br>\n"]
286     }
287     set n [dl-marc-field $zset $no 710 a "Corporate Name" {} ", "]
288     if {$n == 0} {
289         set n [dl-marc-field $zset $no 710 a "Corporate Name" {} ", "]
290     }
291     set n [dl-marc-field $zset $no 245 {a} "Title" {} " "]
292     if {$n > 0} {
293         dd-marc-field $zset $no 245 b "<em>" "</em>"
294         dd-marc-field $zset $no 245 c " " ""
295     } else {
296         dl-marc-field $zset $no 245 {[ab]} "Title" {} " "
297     }
298     dl-marc-field $zset $no 520 a "Abstract" {} ", "
299     dl-marc-field $zset $no 072 * "Subject code" "Subject codes" ", "
300     dl-marc-field $zset $no 650 * "Subject" {} ", "
301     dl-marc-field $zset $no 260 * "Publisher" {} " "
302     dl-marc-field $zset $no 300 * "Physical Description" {} " "
303
304     dl-marc-field-rec $zset $no 500 "Notes" "" "<br>\n" "a" ", "
305
306     dl-marc-field-rec $zset $no 510 "References" "" "<br>\n" "a" ", "
307
308     dl-marc-field-rec $zset $no 511 "Participant note" "" "<br>\n" "a" ", "
309
310     dl-marc-field $zset $no 513 a "Report type" {} ", "
311     dl-marc-field $zset $no 513 b "Period covered" {} ", "
312     dl-marc-field-rec $zset $no 515 "Numbering notes" "" "<br>\n" "a" ", "
313     dl-marc-field-rec $zset $no 516 "Data notes" "" "<br>\n" "a" ", "
314     dl-marc-field-rec $zset $no 518 "Date/time notes" "" "<br>\n" "a" ", "
315
316     dl-marc-field $zset $no 350 a "Price" {} ", "
317     dl-marc-field $zset $no 362 a "Dates of publication" {} ", "
318     dl-marc-field $zset $no 850 a "Holdings" {} ", "
319
320     dl-marc-field-rec $zset $no 270 "Contact name" "" "<br>\n" p ", "
321     if {0} {
322         set n [dl-marc-field $zset $no 270 p "Contact name" {} ", "]
323         if {$n > 0} {
324             html "\n<dl>\n"
325             
326             if {0} {
327                 dl-marc-field $zset $no 270 a "Street" {} ", "
328                 dl-marc-field $zset $no 270 b "City" {} ", "
329                 dl-marc-field $zset $no 270 c "State" {} ", "
330                 dl-marc-field $zset $no 270 e "Zip code" {} ", "
331                 dl-marc-field $zset $no 270 d "Country" {} ", "
332                 dl-marc-field $zset $no 270 m "Network address" {} ", "
333                 dl-marc-field $zset $no 301 a "Service hours" {} ", "
334                 dl-marc-field $zset $no 270 k "Phone" {} ", "
335                 dl-marc-field $zset $no 270 l "Fax" {} ", "
336             } else {
337                 dl-marc-field $zset $no 270 {[abcedmakl]} "Address" {} "<br>\n"
338             }
339             
340             html "\n</dl>\n"
341         }
342     }
343     dl-marc-field $zset $no 010 a "LC control number" {} ", "
344     dl-marc-field $zset $no 010 b "NUCMC control number" {} ", "
345     dl-marc-field $zset $no 020 a "ISBN" {} ", "
346     dl-marc-field $zset $no 022 a "ISSN" {} ", "
347     set url [$zset getMarc $no field 856 * u]
348     set sp [$zset getMarc $no field 856 * 3]
349     if {"x$url" != "x"} {
350         html "<dt><b>URL</b>\n"
351         if {"x$sp" == "x"} {
352             set sp $url
353         }
354         html {<dd><a href="} $url {">} [join $sp] "</a>\n"
355     }
356     dl-marc-field $zset $no 037 {[abc]} "Acquisition" {} "<br>\n"
357     dl-marc-field $zset $no 037 {[f6]} "Form of issue" {} "<br>\n"
358     dl-marc-field $zset $no 537 * "Source of data" {} "<br>\n"
359     dl-marc-field $zset $no 538 * "System details" {} "<br>\n"
360     dl-marc-field $zset $no 787 {[rstw6]} "Related information" {} "<br>\n"
361     dl-marc-field $zset $no 001 * "Local control number" {} ", "
362     html "</dl>\n"
363 }
364
365
366 proc display-rec {from to dfunc tno} {
367     global setNo
368
369     if {$tno > 0} {
370         while {$from <= $to} { 
371             eval "$dfunc z39${tno}.${setNo} $from $tno"
372             incr from
373         }
374     } else {
375         while {$from <= $to} { 
376             eval "$dfunc z39.${setNo} $from 0"
377             incr from
378         }
379     }
380 }
381
382 proc build-scan {t i} {
383     global targets
384
385     set term [wform entry$i]
386     if {$term != ""} {
387         set field [wform menu$i]
388         foreach x [lindex $targets($t) 2] {
389             if {[lindex $x 0] == $field} {
390                 set attr [lindex $x 1]
391             }
392         }
393         return [list $term $attr]
394     }
395     return ""
396 }
397
398 proc build-query {t ilines} {
399     global targets
400
401     set op {}
402     set q {}
403     for {set i 1} {$i <= $ilines} {incr i} {
404         set term [wform entry$i]
405         if {[string length $term] > 0} {
406             set field [wform menu$i]
407             foreach x [lindex $targets($t) 2] {
408                 if {[lindex $x 0] == $field} {
409                     set attr [lindex $x 1]
410                 }
411             }
412             switch $op {
413             And
414                 { set q "@and $q ${attr} ${term}" }
415             Or
416                 { set q "@or $q ${attr} ${term}" }
417             {And not}
418                 { set q "@not $q ${attr} ${term}" }
419             {}
420                 { set q "${attr} ${term}" }
421             }
422             set op [wform logic$i]
423         }
424     }
425     return $q
426 }
427
428 proc z39scan {setNo scanNo tno scanLines scanPos cache} {
429     global hist
430     global sessionWait
431     global targets
432
433     if {$tno > 0} {
434         set zz z39$tno
435         set host $hist($setNo,$tno,host)
436         set idAuth $hist($setNo,$tno,idAuthentication)
437         set database $hist($setNo,$tno,database)
438         set scanAttr $hist($setNo,$tno,scanAttr)
439         set scanTerm $hist($setNo,$tno,$scanNo,scanTerm)
440     } else {
441         set zz z39
442         set host $hist($setNo,host)
443         set idAuth $hist($setNo,idAuthentication)
444         set database $hist($setNo,database)
445         set scanAttr $hist($setNo,scanAttr)
446         set scanTerm $hist($setNo,$scanNo,scanTerm)
447     }
448     if {[catch [list $zz failback fail-response]]} {
449         ir $zz
450     }
451     if {[catch [list set oldHost [$zz connect]]]} {
452         set oldHost ""
453     }
454     set zs $zz.s$scanNo.$setNo
455     $zz callback ok-response
456     $zz failback fail-response
457     if {$oldHost != $host} {
458         catch [list $zz disconnect]
459
460         set sessionWait 0
461         if {[catch [list $zz connect $host]]} {
462             displayError "Cannot connect to target" $host
463             return 0
464         } elseif {$sessionWait == 0} {
465             if {[catch {zwait sessionWait 300}]} {
466                 $zz disconnect
467                 displayError "Cannot connect to target" $host
468                 return 0
469             }
470             if {$sessionWait != 1} {
471                 displayError "Cannot connect to target" $host
472                 return 0
473             }
474         }
475         $zz idAuthentication $idAuth
476         set sessionWait 0
477         if {[catch {$zz init}]} {
478             displayError "Cannot initialize target" $host
479             $zz disconnect
480             return 0
481         }
482         if {[catch {zwait sessionWait 60}]} {
483             displayError "Cannot initialize target" $host
484             $zz disconnect
485             return 0
486         }
487         if {$sessionWait != "1"} {
488             displayError "Cannot initialize target" $host
489             $zz disconnect
490             return 0
491         }
492         if {![$zz initResult]} {
493             set u [$zz userInformationField]
494             $zz disconnect
495             displayError "Cannot initialize target $host" $u
496             return 0
497         }
498     } else {
499         if {$cache && ![catch [list $zs numberOfTermsRequested 5]]} {
500             return 1
501         }
502     }
503     eval $zz databaseNames $database
504
505     ir-scan $zs $zz
506
507     $zs numberOfTermsRequested $scanLines
508     $zs preferredPositionInResponse $scanPos
509
510     $zz callback [list scan-response $zs]
511
512     set sessionWait 0
513     $zs scan "${scanAttr} ${scanTerm}"
514
515     if {[catch {zwait sessionWait 600}]} {
516         wlog debug "timeout/cancel in scan"
517         displayError "Timeout in scan" {}
518         html "</body></html>\n"
519         $zz disconnect
520         return 0
521     }
522     if {$sessionWait == -1} {
523         displayError "Scan fail" "Connection closed"
524         html "</body></html>\n"
525         $zz disconnect
526     }
527     if {$sessionWait != 1} {
528         return 0
529     }
530     return 1
531 }
532
533 proc display-scan {setNo scanNo tno} {
534     global hist
535     global targets
536     global env
537     global sessionId
538
539     if {$tno > 0} {
540         set zz z39$tno
541     } else {
542         set zz z39
543     }
544     set zs $zz.s$scanNo.$setNo
545     set m [$zs numberOfEntriesReturned]
546         
547     if {$m > 0} {
548         set t [lindex [$zs scanLine 0] 1]
549         if {$tno > 0} {
550             set hist($setNo,$tno,[expr $scanNo - 1],scanTerm) $t
551         } else {
552             set hist($setNo,[expr $scanNo - 1],scanTerm) $t
553         }
554         set t [lindex [$zs scanLine [expr $m - 1]] 1]
555         if {$tno > 0} {
556             set hist($setNo,$tno,[expr $scanNo + 1],scanTerm) $t
557         } else {
558             set hist($setNo,[expr $scanNo + 1],scanTerm) $t
559         }
560     }
561     for {set i 0} {$i < $m} {incr i} {
562         regsub -all {\ } [lindex [$zs scanLine $i] 1] + tterm
563         html {<a href="http:} $env(SCRIPT_NAME)
564         html / $sessionId {/query.egw/} $hist($setNo,host) + $setNo +
565         html $hist($setNo,scan) +  $tterm {">}
566         html [lindex [$zs scanLine $i] 1]
567         html {</a>: <em>}
568         html [lindex [$zs scanLine $i] 2]
569         html "</em><br>\n"
570     }
571 }
572
573 proc z39search {setNo piggy tno elements} {
574     global hist
575     global sessionWait
576     global targets
577
578     if {$tno > 0} {
579         set zz z39$tno
580         set host $hist($setNo,$tno,host)
581         set idAuth $hist($setNo,$tno,idAuthentication)
582         set database $hist($setNo,$tno,database)
583         set query $hist($setNo,$tno,query)
584     } else {
585         set zz z39
586         set host $hist($setNo,host)
587         set idAuth $hist($setNo,idAuthentication)
588         set database $hist($setNo,database)
589         set query $hist($setNo,query)
590     }
591     if {[catch [list $zz failback fail-response]]} {
592         ir $zz
593     }
594     if {[catch [list set oldHost [$zz connect]]]} {
595         set oldHost ""
596     }
597     $zz callback ok-response
598     $zz failback fail-response
599     if {$oldHost != $host} {
600         catch [list $zz disconnect]
601
602         set sessionWait 0
603         if {[catch [list $zz connect $host]]} {
604             displayError "Cannot connect to target" $host
605             return 0
606         } elseif {$sessionWait == 0} {
607             if {[catch {zwait sessionWait 300}]} {
608                 $zz disconnect
609                 displayError "Cannot connect to target" $host
610                 return 0
611             }
612             if {$sessionWait != 1} {
613                 displayError "Cannot connect to target" $host
614                 return 0
615             }
616         }
617         $zz idAuthentication $idAuth
618         set sessionWait 0
619         if {[catch {$zz init}]} {
620             displayError "Cannot initialize target" $host
621             $zz disconnect
622             return 0
623         }
624         if {[catch {zwait sessionWait 60}]} {
625             displayError "Cannot initialize target" $host
626             $zz disconnect
627             return 0
628         }
629         if {$sessionWait != "1"} {
630             displayError "Cannot initialize target" $host
631             $zz disconnect
632             return 0
633         }
634         if {![$zz initResult]} {
635             set u [$zz userInformationField]
636             $zz disconnect
637             displayError "Cannot initialize target $host" $u
638             return 0
639         }
640     } else {
641         if {[info exists hist($setNo,hits)] && \
642                 ![catch [list $zz.$setNo smallSetUpperBound 0]]} {
643             return 1
644         }
645         
646     }
647     ir-set $zz.$setNo $zz
648     
649     if {![lindex $targets($host) 5]} {
650         set elements {}
651     }
652     $zz.$setNo smallSetElementSetNames $elements
653     $zz.$setNo mediumSetElementSetNames $elements
654     $zz.$setNo recordElements $elements
655
656     wlog debug "database=$database"
657     eval $zz.$setNo databaseNames $database
658
659     $zz.$setNo preferredRecordSyntax USMARC
660
661     $zz callback [list search-response $zz.$setNo]
662     if {$piggy} {
663         $zz.$setNo largeSetLowerBound 999999
664         $zz.$setNo smallSetUpperBound 0
665         $zz.$setNo mediumSetPresentNumber $hist($setNo,maxPresent)
666     } else {
667         $zz.$setNo largeSetLowerBound 2
668         $zz.$setNo smallSetUpperBound 0
669         $zz.$setNo mediumSetPresentNumber 0
670     }
671     set sessionWait 0
672     $zz.$setNo search $query
673
674     if {[catch {zwait sessionWait 600}]} {
675         wlog debug "timeout/cancel in search"
676         displayError "Timeout in search" {}
677         html "</body></html>\n"
678         $zz disconnect
679         return 0
680     }
681         
682     if {$sessionWait == -1} {
683         displayError "Search fail" "Connection closed"
684         html "</body></html>\n"
685         $zz disconnect
686     }
687     if {$sessionWait != 1} {
688         return 0
689     }
690     set hist($setNo,hits) [$zz.$setNo resultCount]
691     return 1
692 }
693
694 proc init-m-response {i} {
695     global zstatus
696     global zleft
697
698     wlog debug "init-m-response"
699
700     set zstatus($i) 1
701     incr zleft -1
702 }
703
704 proc connect-m-response {i} {
705     global zstatus
706     global zleft
707
708     wlog debug "connect-m-response"
709     z39$i callback [list init-m-response $i]
710     if {[catch {z39$i init}]} {
711         set zstatus($i) -1
712         incr zleft -1
713     }
714 }
715
716 proc fail-m-response {i} {
717     global zstatus
718     global zleft
719     
720     wlog debug "fail-m-response"
721     set zstatus($i) -1
722     incr zleft -1
723 }
724
725 proc search-m-response {setNo i} {
726     global zleft
727     global zstatus
728
729     incr zleft -1
730     set zstatus($i) 2
731 }
732
733 proc z39msearch {setNo piggy elements} {
734     global zleft
735     global zstatus
736     global hist
737     global targets
738
739     set not $hist($setNo,0,host)
740
741     for {set i 1} {$i <= $not} {incr i} {
742         set host $hist($setNo,$i,host)
743         if {[catch {z39 failback fail-response}]} {
744             ir z39$i
745         }
746         if {[catch {set oldHost [z39$i connect]}]} {
747             set oldHost ""
748         }
749         if {$oldHost != $host} {
750             catch {z39$i disconnect}
751         }
752         z39$i callback [list connect-m-response $i]
753         z39$i failback [list fail-m-response $i]
754     }
755     set zleft 0
756     for {set i 1} {$i <= $not} {incr i} {
757         set oldHost [z39$i connect]
758         set host $hist($setNo,$i,host)
759         if {$oldHost == $host} {
760             set zstatus($i) 1
761             continue
762         }
763         z39$i idAuthentication $hist($setNo,$i,idAuthentication)
764         html "Connecting to target " $host " <br>\n"
765         set zstatus($i) -1
766         if {![catch {z39$i connect $host}]} {
767             incr zleft
768         } 
769     }
770     while {$zleft > 0} {
771         wlog debug "Waiting for init response"
772         if {[catch {zwait zleft 10}]} {
773             break
774         }
775     }
776     set zleft 0
777     for {set i 1} {$i <= $not} {incr i} {
778         html "host " $hist($setNo,$i,host) ": "
779         if {$zstatus($i) >= 1} {
780             html "ok <br>\n"
781             ir-set z39$i.$setNo z39$i
782             set hist($setNo,$i,offset) 0
783             eval z39$i.$setNo databaseNames $hist($setNo,$i,database)
784
785             if {![lindex $targets($hist($setNo,$i,host)) 5]} {
786                 set thisElements {}
787             } else {
788                 set thisElements $elements
789             }
790             z39$i.$setNo smallSetElementSetNames $thisElements
791             z39$i.$setNo mediumSetElementSetNames $thisElements
792             z39$i.$setNo recordElements $thisElements
793
794             z39$i.$setNo preferredRecordSyntax USMARC
795             z39$i callback [list search-m-response $setNo $i]
796
797             if {$piggy} {
798                 z39$i.$setNo largeSetLowerBound 999999
799                 z39$i.$setNo smallSetUpperBound 0
800                 z39$i.$setNo mediumSetPresentNumber $hist($setNo,maxPresent)
801             } else {
802                 z39$i.$setNo largeSetLowerBound 2
803                 z39$i.$setNo smallSetUpperBound 0
804                 z39$i.$setNo mediumSetPresentNumber 0
805             }
806             set zstatus($i) 1
807             wlog debug "search " $hist($setNo,$i,query)
808             z39$i.$setNo search $hist($setNo,$i,query)
809             incr zleft
810         } else {
811             html "fail <br>\n"
812         }
813     }
814     while {$zleft > 0} {
815         wlog debug "Waiting for search response"
816         if {[catch {zwait zleft 30}]} {
817             break
818         }
819     }
820     for {set i 1} {$i <= $not} {incr i} {
821         if {$zstatus($i) != 2} continue
822         set status [z39$i.$setNo responseStatus]
823         if {[lindex $status 0] != "NSD"} {
824             set hist($setNo,$i,offset) [z39$i.$setNo numberOfRecordsReturned]
825         }
826     }
827 }
828
829 proc z39present {setNo tno setOffset setMax dfunc elements} {
830     global hist
831     global sessionWait
832     global targets
833
834     if {$tno > 0} {
835         set zz z39$tno
836         set host $hist($setNo,$tno,host)
837     } else {
838         set zz z39
839         set host $hist($setNo,host)
840     }
841
842     if {![lindex $targets($host) 5]} {
843         set elements {}
844     }
845
846     $zz.$setNo elementSetNames $elements
847     $zz.$setNo recordElements $elements
848     set toGet [expr 1 + $setMax - $setOffset]
849
850     $zz callback [list search-response $zz.$setNo]
851
852     while {$setMax > 0 && $toGet > 0} {
853         for {set got 0} {$got < $toGet} {incr got} {
854             if {[$zz.$setNo type [expr $setOffset + $got]] == ""} {
855                 break
856             }
857         }
858         if {$got < $toGet} {
859             set sessionWait 0
860             $zz.$setNo present $setOffset $toGet
861             if {[catch {zwait sessionWait 300}]} {
862                 wlog debug "timeout/cancel in present"
863                 $zz disconnect
864                 break
865             }
866             if {$sessionWait == "0"} {
867                 $zz disconnect
868             }
869             if {$sessionWait != "1"} {
870                 break
871             }
872             set got [$zz.$setNo numberOfRecordsReturned]
873             if {$got <= 0} {
874                 break
875             }
876         }
877         display-rec $setOffset [expr $got + $setOffset - 1] $dfunc $tno
878         set setOffset [expr $got + $setOffset]
879         set toGet [expr 1 + $setMax - $setOffset]
880         wflush
881     }
882 }
883
884 proc z39history {} {
885     global nextSetNo
886     global hist
887     global env
888     global sessionId
889     global targets
890
891     if {![info exists nextSetNo]} {
892         return
893     }
894     html "<h2>History</h2><dl><br>\n"
895     for {set setNo 1} {$setNo < $nextSetNo} {incr setNo} {
896         if {$hist($setNo,scan) > 0} continue
897         set host $hist($setNo,host)
898         html {<dt> } [lindex $targets($host) 0]
899         if {[llength [lindex $targets($host) 1]] > 1} {
900             html ": "
901             foreach b $hist($setNo,database) {
902                 html " $b"
903             }
904         }
905         html {. }
906
907         if {[info exists hist($setNo,hits)]} {
908             html { <a href="http:} $env(SCRIPT_NAME)
909             html / $sessionId {/search.egw/} $setNo + 1
910             html + $hist($setNo,maxPresent)
911             html {">Result</a>: } $hist($setNo,hits) { hits.}
912         } else {
913             html {Search failed.}
914         }
915         html "<dd>\n"
916         html { <a href="http:} $env(SCRIPT_NAME)
917         html / $sessionId {/query.egw/} $host + $setNo 
918         html {">Query</a>: }
919         set op {}
920         for {set i 1} {$i <= 3} {incr i} {
921             if {[string length $hist($setNo,form,entry$i)] > 0} {
922                 html " <b>" [join $op " "] "</b> "
923                 html $hist($setNo,form,menu$i) "=" $hist($setNo,form,entry$i)
924                 set op $hist($setNo,form,logic$i)
925             }
926         }
927     }
928     html "</dl>\n"
929 }
930
931 proc displayError {msga msgb} {
932     html "<p><center>\n"
933     html {<img src="/egwgif/noway.gif" alt="Error">}
934     html "<h2>" $msga "</h2>\n"
935     if {$msgb != ""} {
936         html "<h3>" $msgb "</h3>\n"
937     }
938     html "</center><p>\n"
939 }
940
941 proc button-europagate {} {
942     global useIcons
943     if {$useIcons} {
944         html {<img src="/egwgif/button-egw.gif" alt="Europagate" border=0></a>}
945     } else {
946         html {Europagate | }
947     }
948 }
949
950 proc button-new-target {more} {
951     global useIcons
952     global env
953     global sessionId
954
955     html {<a href="http:} $env(SCRIPT_NAME)
956     html / $sessionId {/targets.egw}
957     if {$useIcons} {
958         html {"><img src="/egwgif/button-new-target.gif" }
959         html {alt="New Target" border=0></a>}
960     } else {
961         html {">New Target</a>}
962         if {$more} {
963             html " | \n"
964         } else {
965             html "\n"
966         }
967     }
968 }
969
970 proc button-view-history {more} {
971     global useIcons
972     global env
973     global sessionId
974
975     html {<a href="http:} $env(SCRIPT_NAME)
976     html / $sessionId {/history.egw}
977     if {$useIcons} {
978         html {"><img src="/egwgif/button-view-history.gif" alt="View History" }
979         html {border=0></a>}
980     } else {
981         html {">View History</a>}
982         if {$more} {
983             html " | \n"
984         } else {
985             html "\n"
986         }
987     }
988 }
989
990 proc button-new-query {more setNo} {
991     global useIcons
992     global env
993     global sessionId
994     global hist
995
996     html {<a href="http:} $env(SCRIPT_NAME)
997     html / $sessionId {/query.egw/} $hist($setNo,host) + $setNo {">}
998     if {$useIcons} {
999         html {<img src="/egwgif/button-new-query.gif" }
1000         html {alt="New Query" border=0></a>}
1001     } else {
1002         html {New Query</a>}
1003         if {$more} {
1004             html " | \n"
1005         } else {
1006             html "\n"
1007         }
1008     }
1009 }
1010
1011 proc maintenance {} {
1012     html {<hr>This page is maintained by }
1013     html {<a href="mailto:pwh@dtv.dk"> Peter Wad Hansen </a>.}
1014     html {Last modified 9. january 1996. <br>}
1015     html {<em> This and the following pages are under construction and }
1016     html {will continue to be so until the end of January 1996.</em>}
1017 }