1 # Web Alpine Config options
2 # $Id: alpine.tcl 1266 2009-07-14 18:39:12Z hubert@u.washington.edu $
3 # ========================================================================
4 # Copyright 2006-2008 University of Washington
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # ========================================================================
14 encoding system
"utf-8"
16 set _wp
(appname
) Alpine
17 set _wp
(admin
) admin
@sample-domain.edu
18 set _wp
(helpdesk
) admin
@sample-domain.edu
19 set _wp
(comments
) help
@sample-domain.edu
21 # List of userid's allowed to request the monitor script output
24 # directory prefix web server uses for web alpine page requests
25 # Note: set to {} if DocumentRoot set to the root of web alpine cgi scripts
26 set _wp
(urlprefix
) webmail
28 # file system path to CGI application files
29 # directory containing web alpine application scripts and supporting tools
30 set _wp
(fileroot
) /usr
/local
/libexec
/alpine
34 # NOTE: Make SURE tclsh and alpine.tcl symlinks in this directory
35 set _wp
(cgipath
) [file join $_wp(fileroot
) cgi
]
37 # CGI scripts implementing U/I, session cookie scope
38 set _wp
(appdir
) alpine
44 # place for CGI scripts not requiring session-key
47 # place for binaries referenced by the CGI scripts
48 set _wp
(bin
) [file join $_wp(fileroot
) bin
]
49 set _wp
(servlet
) alpined
50 set _wp
(pc_servlet
) pc_alpined
51 set _wp
(pldap
) alpineldap
53 # place for config files referenced by the CGI scripts
54 set _wp
(confdir
) [file join $_wp(fileroot
) config
]
55 set _wp
(conffile
) pine.conf
56 set _wp
(defconf
) $_wp(conffile
)
58 # place for library files used by CGI scripts
59 set _wp
(lib
) [file join $_wp(fileroot
) lib
]
61 # directory used temporarily to stage attatched and detached files
62 set _wp
(detachpath
) [file join $_wp(fileroot
) detach
]
64 set _wp
(imagepath
) [file join / $_wp(urlprefix
) images
]
66 set _wp
(buttonpath
) [file join $_wp(imagepath
) buttons silver
]
68 set _wp
(staticondir
) env
70 set _wp
(servername
) [info hostname
]
72 # MUST specify SSL/TLS connection
73 set _wp
(serverport
) {}
74 set _wp
(serverpath
) https
://[file join [join [eval list $_wp(servername
) $_wp(serverport
)] :] $_wp(urlprefix
)]
76 # MAY specify a plaintext connection (comment out if plain support undesired)
78 set _wp
(plainservpath
) http://[file join [join [eval list $_wp(servername
) $_wp(plainport
)] :] $_wp(urlprefix
)]
80 # url of faq page(s) available from initial greeting page
81 #set _wp(faq) "http://www.yourserver/faqs/alpine.html"
83 # url of informational page accessible from initial greeting page
84 set _wp
(releaseblurb
) "$_wp(plainservpath)/alpine/help/release.html"
86 # url of previous version server to be accessible from initial greeting page
87 #set _wp(oldserverpath) "https://previous.version.server.edu:444/"
89 # session id length: make sure the integer count below matches what's built
90 # into the pubcookie: "src/pubcookie/wp_uidmapper_lib.h:#define WP_KEY_LEN 6"
93 # Where and what format the alpined comm socket should take
94 set _wp
(sockdir
) $_wp(tmpdir
)
98 set _wp
(bordercolor
) #FEFAC9
99 set _wp
(menucolor
) #3E2E6D
100 set _wp
(dialogcolor
) #FEFAC9
101 set _wp
(titlecolor
) #000000
102 set _wp
(logodir
) alpine
104 # various timerouts, dimensions and feature settings
107 set _wp
(autodraft
) 300
108 set _wp
(logoutpause
) 60
109 set _wp
(indexlines
) 20
110 set _wp
(indexlinesmax
) 50
111 set _wp
(indexheight
) 24
112 set _wp
(navheight
) 28
114 set _wp
(titleheight
) 34
116 set _wp
(config
) remote_pinerc
118 set _wp
(save_cache_max
) 6
119 set _wp
(fldr_cache_max
) 20
120 set _wp
(fldr_cache_def
) 3
121 set _wp
(statushelp
) 0
122 set _wp
(imgbuttons
) 0
123 set _wp
(keybindings
) 1
124 set _wp
(dictionary
) 0
128 set _wp
(menuargs
) {width
="112" nowrap valign
=top
}
129 set _wp
(ispell
) /usr
/local
/bin
/ispell
131 # Yahoo! User Interface Library location
132 #set _wp(yui) $_wp(serverpath)/$_wp(appdir)/$_wp(ui2dir)/lib/yui
133 set _wp
(yui
) "http://yui.yahooapis.com/2.7.0"
135 # usage reporter - input: username as first command line argument
136 # output: space separated integers usage and total
137 #set _wp(usage) $_wp(bin)/usage.tcl
138 #set _wp(usage_link) "https://uwnetid.washington.edu/disk/"
140 # limit uploads to 1 file at a time, maximum 20MB.
141 set _wp
(uplim_files
) 1
142 set _wp
(uplim_bytes
) 20000000
144 # verify sessid from consistent REMOTE_ADDR (set to 0 for proxying clusters)
147 # set to list of domains for which ssl is NOT required
148 #set _wp(ssl_safe_domains) {}
150 # set to list of address blocks or ranges for which ssl is NOT required
151 #set _wp(ssl_safe_addrs) {}
153 # set this value to zero to turn OFF ssl by default
154 set _wp
(ssl_default
) 1
156 # allow connecting user to specify imap server on greeting page
157 set _wp
(flexserver
) 1
159 # make sure tmp files and such are ours alone to read/write
160 catch {exec umask
044}
162 #fix up indexheight so it isn't too high or too low
163 set _wp
(indexheight
) [expr {$_wp(indexheight
) <= 20 ?
20 : $_wp(indexheight
) >= 30 ?
30 : $_wp(indexheight
)}]
165 # SPAM reporting facility, if set "Report Spam" button appears at top of View Page
166 #set _wp(spamaddr) spamaddr@sample-domain.edu
167 #set _wp(spamfolder) junk-mail
168 #set _wp(spamsubj) "ATTACHED SPAM"
170 # external mail filter config link
171 #set _wp(filter_link) http://delivery-filter.sample-domain.edu/filter/config
173 # external vacation config link
174 #set _wp(vacation_link) http://vacation.sample-domain.edu/vacation/config
177 # Nickname server bindings. If not present, prompt for the
178 # destination of the default pinerc location.
183 $User.deskmail.washington.edu
/ssl
184 $_wp(confdir
)/conf.deskmail
188 # Everybody inherits the cgi, comm packages
189 lappend auto_path
$_wp(lib
)
192 package require WPComm
194 # Recipient of bad news bubbling up from cgi.tcl...
195 cgi_admin_mail_addr
$_wp(admin
)
199 #cgi_mail_relay localhost
200 cgi_mail_relay smtpserver.sample-domain.edu
202 # set permissions for owner-only handling
203 cgi_tmpfile_permissions
0640
206 cgi_file_limit
$_wp(uplim_files
) $_wp(uplim_bytes
)
208 # universal body tag parameters
209 cgi_body_args link
=#0000FF vlink=#000080 alink=#FF0000 marginwidth=0 marginheight=0 topmargin=0 leftmargin=0
211 # Common Images Image definitions
212 cgi_imglink logo
[file join $_wp(imagepath
) logo
$_wp(logodir
) big.gif
] border
=0 "alt=Web Alpine"
213 cgi_imglink smalllogo
[file join $_wp(imagepath
) logo
$_wp(logodir
) small.gif
] border
=0 "alt=About Web Alpine"
214 cgi_imglink background
[file join $_wp(imagepath
) logo
$_wp(logodir
) back.gif
] border
=0 align
=top
215 cgi_imglink dot
[file join $_wp(imagepath
) dot2.gif
] border
=0 align
=top
216 cgi_imglink increas
[file join $_wp(imagepath
) increas4.gif
] border
=0 align
=absmiddle
217 cgi_imglink decreas
[file join $_wp(imagepath
) decreas4.gif
] border
=0 align
=absmiddle
218 cgi_imglink expand
[file join $_wp(imagepath
) b_plus.gif
] border
=0 "alt=Expand" height
=9 width
=9
219 cgi_imglink contract
[file join $_wp(imagepath
) b_minus.gif
] border
=0 "alt=Collapse" height
=9 width
=9
220 cgi_imglink fullhdr
[file join $_wp(imagepath
) hdr.gif
] border
=0 "alt=Full Header"
221 cgi_imglink nofullhdr
[file join $_wp(imagepath
) hdrnon.gif
] border
=0 "alt=Digested Header"
222 cgi_imglink bang
[file join $_wp(imagepath
) caution.gif
] border
=0 "alt=!"
223 cgi_imglink postmark
[file join $_wp(imagepath
) postmark.gif
] border
=0 "alt=New Mail"
224 cgi_imglink gtab
[file join $_wp(imagepath
) tabs gtab.gif
] border
=0 align
=top
225 cgi_imglink gdtab
[file join $_wp(imagepath
) tabs gdtab.gif
] border
=0 align
=top
226 cgi_imglink abtab
[file join $_wp(imagepath
) tabs abtab.gif
] border
=0 align
=top
227 cgi_imglink abdtab
[file join $_wp(imagepath
) tabs abdtab.gif
] border
=0 align
=top
228 cgi_imglink ctab
[file join $_wp(imagepath
) tabs ctab.gif
] border
=0 align
=top
229 cgi_imglink cdtab
[file join $_wp(imagepath
) tabs cdtab.gif
] border
=0 align
=top
230 cgi_imglink ftab
[file join $_wp(imagepath
) tabs ftab.gif
] border
=0 align
=top
231 cgi_imglink fdtab
[file join $_wp(imagepath
) tabs fdtab.gif
] border
=0 align
=top
232 cgi_imglink mltab
[file join $_wp(imagepath
) tabs mltab.gif
] border
=0 align
=top
233 cgi_imglink mldtab
[file join $_wp(imagepath
) tabs mldtab.gif
] border
=0 align
=top
234 cgi_imglink mvtab
[file join $_wp(imagepath
) tabs mvtab.gif
] border
=0 align
=top
235 cgi_imglink mvdtab
[file join $_wp(imagepath
) tabs mvdtab.gif
] border
=0 align
=top
236 cgi_imglink rtab
[file join $_wp(imagepath
) tabs rtab.gif
] border
=0 align
=top
237 cgi_imglink rdtab
[file join $_wp(imagepath
) tabs rdtab.gif
] border
=0 align
=top
241 cgi_link Admin
"Web Alpine Administrator" "mailto:$_wp(admin)"
242 cgi_link Start
"Web Alpine Home Page" "$_wp(serverpath)/session/greeting.tcl" target
=_top
244 # Internally referenced CGI directory root
245 cgi_root
$_wp(serverpath
)
248 # have cgi.tcl convert eols in muiltipart/form-data
249 set _cgi
(no_binary_upload
) 1
251 proc WPSocketName
{sessid
} {
254 return [file join $_wp(sockdir
) [format $_wp(sockpat
) $sessid]]
257 proc WPValidId
{{sessid
{}}} {
260 if {[string length
$sessid] == 0} {
263 # Session Handle: a bit reasonably random number. the format
264 # is convenient for pubcookie auth'd support
266 set rsrc
/dev
/urandom
267 set idbytelength
[expr {$_wp(sessidlen
) * 4}]
268 if {[file readable
$rsrc] && [catch {open $rsrc r
} fp
] == 0} {
270 for {set i
0} {$i < $idbytelength} {incr i
} {
271 if {$i && ($i % 4) == 0} {
275 if {[catch {read $fp 1} n
] == 0} {
277 set x
[expr ($x & 0xff)]
278 append rnum
[format {%02x
} $x]
285 if {[file exists
[WPSocketName
$rnum]]} {
295 # second choice for random numbers
296 if {[string length
$rnum] == 0} {
297 expr srand
([clock seconds
])
298 for {set i
0} {$i < $idbytelength} {incr i
4} {
299 if {$i && ($i % 4) == 0} {
303 append rnum
[format {%08x
} [expr int
((100000000 * rand
()))]]
307 # generate a session ID
308 set _wp
(sessid
) $rnum
310 set sessidparts
[split $sessid {@}]
311 switch [llength $sessidparts] {
313 set _wp
(sessid
) $sessid
316 if {[string compare
[string tolower
[lindex $sessidparts 1]] [string tolower
[info hostname
]]]} {
317 regexp {^
([a-zA-Z
]*://).
*} [cgi_root
] match proto
318 error [list redirect
"${proto}[lindex $sessidparts 1]:$env(SERVER_PORT)?$env(QUERY_STRING)"]
320 set _wp
(sessid
) [lindex $sessidparts 0]
324 error "Malformed Session ID: $sessid"
329 set _wp
(sockname
) [WPSocketName
$_wp(sessid
)]
331 if {[info exists _wp
(cumulative
)]} {
332 rename WPCmd WPCmd.orig
333 rename WPCmdTimed WPCmd
336 if {[info exists _wp
(hostcheck
)] && $_wp(hostcheck
) == 1 && ![info exists created
]
337 && [catch {WPCmd
set wp_client
} client
] == 0
338 && (([info exists env
(REMOTE_ADDR
)] && [string length
$env(REMOTE_ADDR
)] && [string compare
$client $env(REMOTE_ADDR
)])
339 ||
([info exists env
(REMOTE_HOST
)] && [string length
$env(REMOTE_HOST
)] && [string compare
$client $env(REMOTE_HOST
)]))} {
340 error "Request from unrecognized client"
352 if {[info exists _wp
(cleanup
)]} {
353 foreach item
$_wp(cleanup
) {
359 proc WPEval
{vars cmd
} {
362 if {$_wp(cmdtime
) ||
$_wp(evaltime
)} {
363 set _wp
(cumulative
) 0
367 set _wp
(vars
) [linsert $vars 0 [list sessid
"Missing Session ID"]]
371 if {$_wp(debug
) > 1} {
376 if {[catch {WPGetInputAndID sessid
}]} {
380 foreach item
$_wp(vars
) {
381 if {[catch {eval WPImport
$item} errstr
]} {
382 WPInfoPage
"Web Alpine Error" [font size
=+2 $errstr] "Please close this window."
387 # evaluate the given script
388 if {[catch {cgi_buffer
$_wp(cmd
)} result
]} {
392 if {[string index
$result 0] == "_"} {
393 switch -- [lindex $result 0] {
395 WPInfoPage
[lindex $result 1] [font size
=+2 [lindex $result 2]] [lindex $result 3]
398 switch -regexp -- [lindex $result 2] {
399 "[Ii]nactive [Ss]ession" {
403 if {[string length
[lindex $result 3]]} {
404 set remedy
[lindex $result 3]
406 set remedy
" Click your browser's Back button to return to previous page."
408 WPInfoPage
"[lindex $result 1] Error" [font size
=+2 [lindex $result 2]] \
409 "Please report this to the [cgi_link Admin].$remedy"
415 cgi_redirect
[lindex $result 1]
418 cgi_html
{ cgi_body
{} }
421 if {[string length
[lindex $result 1]] == 0} {
422 set result
"Indeterminate error"
425 WPInfoPage
"Web Alpine Error" [font size
=+2 [lindex $result 1]] "Please close this window."
428 if {[string length
$result]} {
429 WPInfoPage
"Web Alpine Error" [font size
=+2 "Eval Error: $result"] \
430 "Please complain to the [cgi_link Admin]. Click Back button to return to previous page."
432 WPInfoPage
"Web Alpine Error" [font size
=+2 "Indeterminate error response"] \
433 "Please complain to the [cgi_link Admin] and click Back button to return to previous page."
438 if {[regexp {[Ii
]nactive
[Ss
]ession
} $result]} {
441 WPInfoPage
"Web Alpine Error" [font size
=+2 "Error: $result"] \
442 "Please report this to the [cgi_link Admin]. Try clicking your browser's Back button to return to a working page."
446 catch {cgi_puts
$result}
454 if {[info exists _wp
(cumulative
)]} {
455 WPdebug
"Cumulative Eval: $_wp(cumulative)"
456 unset _wp
(cumulative
)
460 proc WPGetInputAndID
{_sessid
} {
462 upvar $_sessid sessid
464 # Import data and validate it
465 if {[catch {cgi_input
"sessid=8543949466398&"} result
]} {
466 WPInfoPage
"Web Alpine Error" [font size
=+2 $result] "Please close this window."
467 error "Cannot get CGI Input"
470 if {[catch {WPImport sessid
"Missing Session ID"} errstr
]} {
471 if {[regexp {.
*sessid.
*no such.
*} $errstr]} {
472 WPInactivePage
[list "Your browser may have failed to send the necessary <i>cookie</i> information. Please verify your browser configuration has cookies enabled."]
474 WPInfoPage
"Web Alpine Error" [font size
=+2 $errstr] "Please close this window."
477 error "Session ID Failure"
479 # initialization here
480 if {[catch {WPValidId
$sessid} result
]} {
481 if {[string compare
[lindex $result 0] redirect
]} {
482 WPInfoPage
"Web Alpine Error" [font size
=+2 "$result"] \
483 "Please complain to the [cgi_link Admin] and visit the [cgi_link Start] later."
486 cgi_redirect
[lindex $result 1]
490 error "Unrecoverable Error"
491 } elseif
{$_wp(sessid
) == 0} {
493 error "Inactive Session"
496 if {[catch {WPCmd
set serverroot
} serverroot
] == 0} {
502 proc WPCmdEval
{args
} {
509 return [WPSend
$_wp(sockname
) $args]
512 proc WPCmdTimed
{args
} {
515 set t
[lindex [time {set r
[WPSend
$_wp(sockname
) $args]}] 0]
516 incr _wp
(cumulative
) $t
519 WPdebug
"time $t : $args"
525 proc WPLoadCGIVar
{_var
} {
528 if {[catch {cgi_import_as
$_var var
} result
]
529 && [catch {WPCmd
set $_var} var
]
530 && [catch {cgi_import_cookie_as
$_var var
} result
]} {
531 error [list _action
"Import Cookie $_var" $result]
535 proc WPLoadCGIVarAs
{_var _varas
} {
538 if {[catch {cgi_import_as
$_var varas
} result
]
539 && [catch {WPCmd
set $_var} varas
]
540 && [catch {cgi_import_cookie_as
$_var varas
} result
]} {
545 proc WPImport
{valname
{errstring
""} {default 0}} {
548 if {[catch {cgi_import_as
$valname val
} result
]} {
549 if {[catch {WPCmd
set $valname} val
]} {
550 if {[catch {cgi_import_cookie_as
$valname val
} result
]} {
551 if {[string length
$errstring] > 0} {
552 error "$errstring: $result"
562 proc WPExportCookie
{name value
{scope
""}} {
565 cgi_cookie_set
$name=$value "path=[file join / $_wp(urlprefix) $scope]"
569 # handle dynamic sizing of images showing thread relationships
570 proc WPThreadImageLink
{t h
} {
573 return "<img src=\"[file join $_wp(imagepath) ${t}.gif]\" border=0 align=top height=${h} width=14>"
577 proc WPInactivePage
{{reasons
""}} {
583 WPInfoPage
"Inactive Session" \
584 "[font size=+2 "Web Alpine Session No Longer Active
"]" \
585 "There are several reasons why a session might become inactive.<ul><li>A bookmarked reference to a Web Alpine page.<li>Failed periodic page reload due to browser/system suspension associated with power saving mode, etc.${l}</ul><p>Please visit the [cgi_link Start] to start a new session."
588 proc WPInfoPage
{title exp1
{exp2
""} {imgurl
{}} {exp3
""}} {
596 cgi_stylesheet
[file join / $_wp(urlprefix
) $_wp(pubdir
) standard.css
]
600 cgi_table height
="20%" {
603 cgi_puts
[cgi_nbspace
]
609 cgi_table border
=0 width
=500 cellpadding
=3 {
611 cgi_table_data align
=center rowspan
=3 {
612 if {[string length
$imgurl]} {
613 cgi_put
[cgi_url
[cgi_imglink logo
] $imgurl]
615 cgi_put
[cgi_imglink logo
]
619 cgi_table_data rowspan
=3 {
630 if {[string length
$exp3]} {
632 cgi_table_data
"style=\"border: 1px solid red; background-color: pink\"" {
638 if {[string length
$exp2]} {
652 proc WPimg
{image {extension gif
}} {
655 return [file join $_wp(imagepath
) ${image}.
${extension
}]
658 proc WPCharValue
{c
} {
663 proc WPPercentQuote
{arg
{exclude
{}}} {
664 set t
"\[^0-9a-zA-Z_${exclude}\]"
665 if {[regsub -all $t $arg {[format "%%%.2X" [WPCharValue
"\\&"]]} subarg
]} {
666 set x
[subst $subarg]
674 regsub -all {([\\'
])} $l {\\\1} l
678 proc WPurl
{cmd cmdargs
text explanation args
} {
681 lappend urlargs
$text
683 if {[regexp "^java*" $cmd] == 0 && [string first .
$cmd] < 0} {
684 append urlargs
".tcl"
687 if {[string length
$cmdargs]} {
688 if {[set i
[string first
"?" $cmdargs]] >= 0} {
689 append urlargs
"[cgi_quote_url [string range $cmdargs 0 [expr {$i - 1}]]]?[cgi_quote_url [string range $cmdargs [incr i] end]]"
691 append urlargs
"?[cgi_quote_url $cmdargs]"
695 if {$_wp(statushelp
)} {
696 lappend urlargs
[WPmouseover
$explanation]
697 lappend urlargs
"onMouseOut=window.status=''"
700 return [eval "cgi_url $urlargs $args"]
703 proc WPMenuURL
{cmd cmdargs
text explanation args
} {
704 return [WPurl
$cmd $cmdargs $text $explanation class
=menubar
[join $args]]
707 proc WPGetTDFontSize
{{ih
24}} {
708 if {$ih <= 20 } {return 12}
709 if {$ih >= 30 } {return 24}
710 return [expr {$ih - 8}]
713 proc WPGetviewFontSize
{{ih
24}} {
714 if {$ih <= 20 } {return 8}
715 if {$ih >= 30 } {return 13}
716 return [expr {($ih / 2) - 2}]
719 proc WPIndexLineHeight
{{ih
0}} {
722 set ih
[WPCmd PEInfo indexheight
]
723 if {[string length
$ih] == 0 ||
$ih <= 0} {
724 set ih
$_wp(indexheight
)
727 return [expr {($ih < 20) ?
20 : $ih}]
730 proc WPStyleSheets
{{ih
0}} {
733 cgi_stylesheet
[file join / $_wp(urlprefix
) $_wp(pubdir
) standard.css
]
736 set ih
[WPIndexLineHeight
]
739 cgi_puts
"<style type='text/css'>\nTD { font-size: [WPGetTDFontSize $ih]px }\n.view {font-size: [WPGetviewFontSize $ih]pt }\n</style>"
743 proc WPStdScripts
{{ih
0}} {
746 set ih
[WPStyleSheets
$ih]
748 cgi_script language
="JavaScript" src
="[file join / $_wp(urlprefix) $_wp(pubdir) standard.js]" {}
749 cgi_script language
="JavaScript1.3" {cgi_put
"js_version = '1.3';"}
751 cgi_puts
"function getIndexHeight(){return $ih}"
755 proc WPStdHttpHdrs
{{ctype
{}} {expires
0}} {
758 # set date and expires headers the same to prevent caching
759 # Date: Tue, 15 Nov 1994 08:12:31 GMT
760 set doctime
[clock seconds
]
762 if {[string length
$ctype]} {
763 cgi_content_type
$ctype
768 cgi_puts
"Date: [clock format $doctime -gmt true -format "%a
, %d
%b
%Y
%H
:%M
:%S GMT
"]"
771 cgi_puts
"Cache-Control: no-cache"
772 cgi_puts
"Expires: [clock format [expr {$doctime - 31536000}] -gmt true -format "%a
, %d
%b
%Y
%H
:%M
:%S GMT
"]"
773 } elseif
{$expires > 0} {
774 cgi_puts
"Expires: [clock format [expr {$doctime + ($expires * 60)}] -gmt true -format "%a
, %d
%b
%Y
%H
:%M
:%S GMT
"]"
778 proc WPStdHtmlHdr
{pagetitle
{pagescript
""} {newmail
0}} {
787 cgi_title
"${nm}Web Alpine - $pagetitle"
788 # cgi_base "href=$_wp(serverpath)/"
789 if {[info exists _wp
(nocache
)]} {
790 cgi_http_equiv Pragma no-cache
793 # cgi_http_equiv Expires $_wp(docdate)
794 cgi_meta
"name=Web Alpine" content
=[clock format [file mtime
[info script
]] -format "%y%m%d/%H%M"]
795 if {[catch {WPCmd
set nojs
} nojs
] ||
$nojs != 1} {
796 cgi_script type
="text/javascript" language
="JavaScript" {
797 cgi_puts
"if(self != top) top.location.href = location.href;"
798 cgi_puts
"js_version = '1.0';"
802 cgi_put
"<link rel=\"icon\" href=\"[cgi_root]/favicon.ico\" type=\"image/x-icon\">"
803 cgi_put
"<link rel=\"shortcut icon\" href=\"[cgi_root]/favicon.ico\" type=\"image/x-icon\"> "
806 proc WPHtmlHdrReload
{pagescript
} {
809 if {[regexp {\?} $pagescript]} {
815 cgi_http_equiv Refresh
"$_wp(refresh); url=[cgi_root]/${pagescript}${c}reload=1"
818 proc WPNewMail
{reload
{viewpage msgview.tcl
}} {
820 if {[catch {WPCmd PEMailbox newmail
$reload} newmail
]} {
821 return -code error $newmail
826 if {[set msgsnew
[lindex $newmail 0]] > 0} {
827 if {[string length
$viewpage]} {
828 if {[string first
{?
} $viewpage] < 0} {
834 set newurl
"${viewpage}${delim}uid=[lindex $newmail 1]"
836 set newurl
[lindex $newmail 1]
839 set newicon
"postmark"
840 set newtext
[cgi_quote_html
[WPCmd PEMailbox newmailstatmsg
]]
842 if {[WPCmd PEInfo feature enable-newmail-sound
]} {
843 #set audio sounds/mail_msg.wav
844 set audio
/sounds
/ding.wav
846 set newsound
"<bgsound src=\"$audio\" loop=\"1\" volume=\"100\">"
848 set newsound
"<embed src=\"$audio\" autostart=\"true\" hidden width=0 height=0 loop=\"false\"><noembed><bgsound src=\"$audio\" loop=\"1\"></noembed>"
854 if {0 == [string length
$newtext]} {
855 set newtext
"You have $msgsnew new message[WPplural $msgsnew]"
858 lappend newref
[list $newtext $newicon $newurl $newsound]
861 if {[set deleted
[lindex $newmail 2]] > 0} {
862 set newtext
"$deleted Message[WPplural $deleted] removed from folder"
863 lappend newref
[list $newtext "" ""]
866 foreach statmsg
[WPStatusMsgs
] {
867 lappend newref
[list $statmsg "" ""]
868 WPCmd PEInfo statmsg
""
872 WPCmd PEMailbox newmailreset
878 proc WPStatusMsgs
{} {
881 if {[catch {WPCmd PEInfo statmsgs
} statmsgs
] == 0} {
882 foreach statmsg
$statmsgs {
883 if {[string length
$statmsg] > 0 && [string compare
$statmsg $lastmsg]} {
884 if {[regexp "^Pinerc \(.+\) NOT saved$" $statmsg]} {
885 lappend retmsgs
"Another Pine/WebPine session may be running. Settings cannot be saved."
887 lappend retmsgs
$statmsg
898 proc WPStatusIcon
{uid
{extension gif
} {statbits
""}} {
901 if {[string length
$statbits] == 0} {
902 set statbits
[WPCmd PEMessage
$uid statusbits
]
905 if {[string index
$statbits 0]} {
912 set fullalt
"Viewed "
915 if {[string index
$statbits 3]} {
917 set alt
"*[string range $alt 1 end]"
918 set fullaltend
", important message"
919 } elseif
{([string index
$statbits 4] ||
[string index
$statbits 5])} {
921 set alt
"+[string range $alt 1 end]"
922 set fullaltend
" message to you"
925 if {[string index
$statbits 2]} {
927 set alt
"[string range $alt 0 0]A"
928 append fullalt
", answered"
931 if {[string index
$statbits 1]} {
933 set alt
"[string range $alt 0 0]D"
934 append fullalt
", deleted"
937 if {[info exists fullaltend
]} {
938 append fullalt
$fullaltend
940 append fullalt
message
943 regsub -all { } $alt {\ 
;} alt
945 return [list [file join $_wp(imagepath
) $_wp(staticondir
) ${sicon
}.
${extension
}] i_
${uid
} $alt $fullalt]
948 proc WPStatusLabel
{uid
} {
951 set statbits
[WPCmd PEMessage
$uid statusbits
]
953 if {[string index
$statbits 0]} {
959 if {[string index
$statbits 3]} {
963 if {[string index
$statbits 1]} {
967 if {[string index
$statbits 2]} {
974 proc WPStatusImg
{uid
} {
975 set sicon
[WPStatusIcon
$uid]
976 return [cgi_img
[lindex $sicon 0] name
=[lindex $sicon 1] id
=[lindex $sicon 1] height
=16 width
=42 border
=0 alt
=[lindex $sicon 3]]
979 proc WPSessionState
{args
} {
980 switch [llength $args] {
983 if {[catch {WPCmd PEInfo alpinestate
} state_list
] == 0} {
984 array set state_array
$state_list
985 if {[llength $args] == 1} {
986 return $state_array([lindex $args 0])
988 set state_array
([lindex $args 0]) [lindex $args 1]
989 set state_list
[array get state_array
]
990 if {[catch {WPCmd PEInfo alpinestate
$state_list} result
]} {
991 error "Can't set session state : $result"
995 error "Can't read session state"
999 error "Unknown SessionState Parameters: $args"
1004 proc WPScriptVersion
{tag
{inc
0}} {
1005 if {[catch {WPCmd
set wp_script_version
} sv
]} {
1006 set versions
($tag) [expr int
((1000 * rand
()))]
1007 set sv
[array get versions
]
1008 catch {WPCmd
set wp_script_version
$sv}
1010 array set versions
$sv
1012 if {![info exists versions
($tag)]} {
1013 set versions
($tag) [expr int
((1000 * rand
()))]
1014 set sv
[array get versions
]
1015 catch {WPCmd
set wp_script_version
$sv}
1017 incr versions
($tag) $inc
1018 set sv
[array get versions
]
1019 catch {WPCmd
set wp_script_version
$sv}
1023 return $versions($tag)
1026 proc WPplural
{count
} {
1034 proc WPcomma
{number
{dot
,}} {
1037 while {[set n
[string length
$number]] > 3} {
1038 set x
"${dot}[string range $number [incr n -3] end]$x"
1039 set number
[string range
$number 0 [incr n
-1]]
1048 return [expr {[info exists env
(HTTP_USER_AGENT
)] == 1 && [string first MSIE
$env(HTTP_USER_AGENT
)] >= 0}]
1054 return [expr {[info exists env
(HTTP_USER_AGENT
)] && (([regexp {^Mozilla
/([0-9]).
[0-9]+} $env(HTTP_USER_AGENT
) match majorversion
] && $majorversion > 4) ||
([regexp {Opera
([0-9])\.
[0-9]+} $env(HTTP_USER_AGENT
) match majorversion
] && $majorversion > 5))}]
1057 proc WPdebug
{args
} {
1060 switch [lindex $args 0] {
1062 if {[regexp {^
([0-9])+$} [lindex $args 1]]} {
1063 WPSend
$_wp(sockname
) [subst {PEDebug level
[lindex $args 1]}]
1067 switch [lindex $args 1] {
1069 WPSend
$_wp(sockname
) [subst {ePEDebug imap
4}]
1072 WPSend
$_wp(sockname
) [subst {PEDebug imap
0}]
1077 WPSend
$_wp(sockname
) "PEDebug write [list [list [file tail [info script]]: [lrange $args 0 end]]]"
1082 proc WPdebugstack
{} {
1085 for {set n
[expr {[info level
] - 1}]} {$n > 0} {incr n
-1} {
1086 append stack
"$n) [info level $n]\n"
1092 ##############################################################
1093 # routines to improve integration with cgi.tcl
1094 ##############################################################
1096 # routine exposing some of cgi.tcl's innards.
1097 # Should be exported by cgi.tcl package.
1098 proc reset_cgi_state
{} {
1101 catch {unset _cgi
(http_head_in_progress
)}
1102 catch {unset _cgi
(http_head_done
)}
1103 catch {unset _cgi
(http_status_done
)}
1104 catch {unset _cgi
(html_in_progress
)}
1105 catch {unset _cgi
(head_in_progress
)}
1106 catch {unset _cgi
(head_done
)}
1107 catch {unset _cgi
(html_done
)}
1108 catch {unset _cgi
(head_suppress_tag
)}
1109 catch {unset _cgi
(body_in_progress
)}
1110 catch {unset _cgi
(tag_in_progress
)}
1111 catch {unset _cgi
(form_in_progress
)}
1112 catch {unset _cgi
(close_proc
)}
1114 if {[info exists _cgi
(returnIndex
)]} {
1115 while {[set _cgi
(returnIndex
)] > 0} {
1116 incr _cgi
(returnIndex
) -1
1118 rename cgi_puts
$_cgi(returnIndex
) cgi_puts
1123 ###############################################################
1124 # routines to process (and be called in) html template files
1125 ###############################################################
1127 proc html_readfile
{file} {
1128 set x
[open $file "r"]
1129 set result
[read $x]
1134 proc html_eval
{_vars_ _this_
} {
1135 foreach {_i_ _j_
} $_vars_ {
1136 if {$_i_ == "global"} {global $_j_} {set $_i_ $_j_}
1138 unset _vars_ _i_ _j_
1139 return [subst $_this_]
1142 proc html_loop
{varslist
text} {
1144 foreach {vars
} $varslist {
1145 append result
[html_eval
$vars $text]