1 # ===================================================================== 2 # group-stuff.rc: W-TW common prologue with group-related checks. 3 # 4 # Copyright (c) 2009-2014 Carlo Strozzi 5 # 6 # This program is free software; you can redistribute it and/or modify 7 # it under the terms of the GNU General Public License as published by 8 # the Free Software Foundation; version 2 dated June, 1991. 9 # 10 # This program is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU General Public License for more details. 14 # 15 # You should have received a copy of the GNU General Public License 16 # along with this program; if not, write to the Free Software 17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 # 19 # ===================================================================== 20 21 tmp1 = /dev/null 22 23 need_default = () 24 25 # Check the first most important arg. 26 {~ $'cgi.group' () || ~ $'cgi.group' tw-*} && csaExit.fault 1000 27 28 # Enable global editor sections in templates if appropriate. 29 if (~ ,$TNS_AUTH_GRP, *,editor,*) { 30 tpl.if.tw.global.editor = () 31 tpl.fi.tw.global.editor = () 32 } 33 34 # Although this is already done by _ifsections() in most cases, 35 # for it to work also with csaExit.{ok,fault} it must be done 36 # also here. 37 38 if (csaTrue $CSA_AUTH_OK) { 39 tpl.if.tw.public = '(::DEL:)' 40 tpl.fi.tw.public = '(:DEL::)' 41 } else { 42 tpl.if.tw.public = () 43 tpl.fi.tw.public = () 44 } 45 46 # Set provisional group metadata as supplied by the user. 47 tpl.var.tw.group.unx = $'cgi.group' 48 tpl.var.tw.group = $'cgi.page.group' 49 50 tw_gstem = $CSA_ROOT/var/pages/$CSA_LANG/$'cgi.group' 51 52 # If a group-specific custom template directory does not exist 53 # then set CSA_TPL_ROOT to a default value. This is meant to 54 # make it easy to set up a custom template directory which is 55 # common to all page groups in the current language. 56 57 if (test -d $CSA_ROOT/forms/$CSA_LANG/$'cgi.group') { 58 CSA_TPL_ROOT = $CSA_ROOT/forms/$CSA_LANG/$'cgi.group' 59 tpl.var.html.base = $CSA_URL/$CSA_LANG/$'tpl.var.tw.group.unx' 60 } else { 61 CSA_TPL_ROOT = $CSA_ROOT/forms/$CSA_LANG/tw-default 62 tpl.var.html.base = $CSA_URL/$CSA_LANG/tw-default 63 } 64 65 tw_dstem = $CSA_ROOT/lib/default 66 67 # Account for the fact that templates are created by the client. 68 CSA_TPL_SAFEPATH = ($CSA_INSTALL/lib $tw_dstem 69 $TMPDIR $tw_gstem $CSA_TPL_ROOT 70 $CSA_DOCROOT/$CSA_LANG/$TNS_ATTACH_PUBDIR) 71 72 tpl.var.tw.group.unx = $'cgi.group' 73 74 # Add any exemptions as shown. 75 #if (!~ $CSA_PGM($#CSA_PGM) logOut) { 76 CSA_EXIT_SCRIPT = $CSA_ROOT/lib/exit-stuff.rc 77 #} 78 79 # Create the language-specific local group defaults if necessary. 80 81 if (!csaIsFullPath --exists --quiet \ 82 $CSA_ROOT/var/pages/$CSA_LANG/tw-default+cf) { 83 csaLock $CSA_ROOT/var/pages/$CSA_LANG/tw-default+cf || 84 csaExit.fault 85 # Test again, to prevent races. 86 if (!csaIsFullPath --exists --quiet \ 87 $CSA_ROOT/var/pages/$CSA_LANG/tw-default+cf) { 88 need_default = 1 89 } 90 } 91 92 ~ $need_default () && . $CSA_ROOT/var/pages/$CSA_LANG/tw-default+cf 93 94 # Read the group-level configuration file if available (no TPC needed here). 95 if (csaIsFullPath --exists --quiet $tw_gstem+cf) { 96 97 . $tw_gstem+cf 98 99 # Create group-level free-form rc(1) script if necessary (no TPC 100 # needed here). This file is meant to host group-specific rc(1) code 101 # that may otherwise go lost if stored directly into group+cf, because 102 # of the group+mux processing below. The file will then be sourced 103 # further down, after any updates to group+cf have been applied. 104 105 csaIsFullPath --exists --quiet $tw_gstem+cod || 106 touch $tw_gstem+cod || csaExit.fault 0009 $tw_gstem+cod 107 108 # Process any pending updates to group-level configuration settings. 109 if (csaIsFullPath --exists --quiet $tw_gstem+mux && 110 test $tw_gstem+mux -nt $tw_gstem+cf) { 111 112 # Set Principal Lock Semaphore(s) (PLS). 113 csaLock $CSA_ROOT/var/pages/$CSA_LANG/group+dat || csaExit.fault 114 115 # Was the file processed by someone else in the meantime ? 116 if (csaIsFullPath --exists --quiet $tw_gstem+mux && 117 test $tw_gstem+mux -nt $tw_gstem+cf) { 118 119 # Create a backup copy if not done yet, as it may have 120 # been created manually and it may contain comments, 121 # additional code, etc. 122 123 csaIsFullPath --exists --quiet $tw_gstem+bak || 124 cp $tw_gstem+rc $tw_gstem+bak || csaExit.fault 0003 cp 125 126 csaMkTemp gmux_tmp 127 128 # Dump env vars and retain only the group-related ones. 129 { printf '\001var_name\t\001var_value\n' 130 envtotable | tabletolist --no-^(header footer unescape) --lists 131 } | sorttable | jointable $CSA_ROOT/lib/group-vars.dat | 132 tail -n +2 > $gmux_tmp 133 csaStatus || 134 csaExit.fault 0003 envtotable/tabletolist/sorttable/jointable/tail 135 136 # Pick allowed group-related vars from group+mux. 137 { printf '\001var_name\t\001var_value\n' 138 muxtotable < $tw_gstem+mux | 139 tabletolist --no-^(header footer unescape) --lists 140 } | sorttable | jointable $CSA_ROOT/lib/group-vars.dat | 141 tail -n +2 >> $gmux_tmp 142 csaStatus || 143 csaExit.fault 0003 envtotable/tabletolist/sorttable/jointable/tail 144 145 muxtotable < $gmux_tmp | csa-tbl2rc \ 146 --^(lists union no-count break prefix) ..NONE.. > $tw_gstem+cf 147 148 csaStatus || csaExit.fault 0003 muxtotable/csa-tbl2rc 149 150 . $tw_gstem+cf # load the updated values. 151 } 152 153 # Release PLS ASAP. 154 csaUnlock $CSA_ROOT/var/pages/$CSA_LANG/group+dat 155 } 156 157 # Load subcat-level group settings, if available. This must come 158 # *before* the loading of the alt-type defs below. Note that the 159 # per-subcat settings are not sought for if the subcat token is to be 160 # interpreted as a search pattern. See also 'rpclib/groupPageMap' . 161 162 if (~ $'cgi.subcat' [a-z]* && !~ $'cgi.scope' f* F* && 163 csaIsFullPath --exists --quiet $tw_gstem.s.$'cgi.subcat'+cf) { 164 165 . $tw_gstem.s.$'cgi.subcat'+cf 166 167 # Process any pending updates to subcat-level configuration settings. 168 if (csaIsFullPath --exists --quiet $tw_gstem.s.$'cgi.subcat'+mux && 169 test $tw_gstem.s.$'cgi.subcat'+mux -nt \ 170 $tw_gstem.s.$'cgi.subcat'+cf) { 171 172 # Set Principal Lock Semaphore(s) (PLS). 173 csaLock $CSA_ROOT/var/pages/$CSA_LANG/group+dat || csaExit.fault 174 175 # Was the file processed by someone else in the meantime ? 176 if (csaIsFullPath --exists --quiet $tw_gstem.s.$'cgi.subcat'+mux && 177 test $tw_gstem.s.$'cgi.subcat'+mux -nt \ 178 $tw_gstem.s.$'cgi.subcat'+cf) { 179 180 # Create a backup copy if not done yet, as it may have 181 # been created manually and it may contain comments, 182 # additional code, etc. 183 184 csaIsFullPath --exists --quiet $tw_gstem.s.$'cgi.subcat'+bak || 185 cp $tw_gstem.s.$'cgi.subcat'+rc $tw_gstem.s.$'cgi.subcat'+bak || 186 csaExit.fault 0003 cp 187 188 # Create work file only if not already created. 189 csaIsFullPath --quiet $gmux_tmp || csaMkTemp gmux_tmp 190 191 # Dump env vars and retain only the group-related ones. 192 # The set of vars that are allowed at the subcat level 193 # is the same of the one at the group level. 194 { printf '\001var_name\t\001var_value\n' 195 envtotable | tabletolist --no-^(header footer unescape) --lists 196 } | sorttable | jointable $CSA_ROOT/lib/group-vars.dat | 197 tail -n +2 > $gmux_tmp 198 csaStatus || 199 csaExit.fault 0003 envtotable/tabletolist/sorttable/jointable/tail 200 201 # Pick allowed group-related vars from group.s.subcat+mux. 202 { printf '\001var_name\t\001var_value\n' 203 muxtotable < $tw_gstem.s.$'cgi.subcat'+mux | 204 tabletolist --no-^(header footer unescape) --lists 205 } | sorttable | jointable $CSA_ROOT/lib/group-vars.dat | 206 tail -n +2 >> $gmux_tmp 207 csaStatus || 208 csaExit.fault 0003 envtotable/tabletolist/sorttable/jointable/tail 209 210 muxtotable < $gmux_tmp | csa-tbl2rc \ 211 --^(lists union no-count break prefix) ..NONE.. \ 212 > $tw_gstem.s.$'cgi.subcat'+cf 213 214 csaStatus || csaExit.fault 0003 muxtotable/csa-tbl2rc 215 216 . $tw_gstem.s.$'cgi.subcat'+cf # load the updated values. 217 } 218 219 # Release PLS ASAP. 220 csaUnlock $CSA_ROOT/var/pages/$CSA_LANG/group+dat 221 } 222 } 223 224 # Load "alternate" group settings, if available. This is mostly used 225 # to allow for different "personalities", depending on the execution 226 # context. For example, it can be used to provide a specific set of 227 # response templates when a program is called with an IFRAME from within 228 # a different TW group. To date, only 'rpclib/groupPageMap' uses this 229 # capability, see the relevant source code for details. 230 231 if (~ $'cgi.style' alt-* && csaIsFullPath --exists --quiet \ 232 $tw_gstem.a.$'cgi.style'+cf) { 233 . $tw_gstem.a.$'cgi.style'+cf 234 235 # Process any pending updates to alternate configuration settings. 236 if (csaIsFullPath --exists --quiet $tw_gstem.a.$'cgi.style'+mux && 237 test $tw_gstem.a.$'cgi.style'+mux -nt \ 238 $tw_gstem.a.$'cgi.style'+cf) { 239 240 # Set Principal Lock Semaphore(s) (PLS). 241 csaLock $CSA_ROOT/var/pages/$CSA_LANG/group+dat || csaExit.fault 242 243 # Was the file processed by someone else in the meantime ? 244 if (csaIsFullPath --exists --quiet $tw_gstem.a.$'cgi.style'+mux && 245 test $tw_gstem.a.$'cgi.style'+mux -nt \ 246 $tw_gstem.a.$'cgi.style'+cf) { 247 248 # Create a backup copy if not done yet, as it may have 249 # been created manually and it may contain comments, 250 # additional code, etc. 251 252 csaIsFullPath --exists --quiet $tw_gstem.a.$'cgi.style'+bak || 253 cp $tw_gstem.s.$'cgi.subcat'+rc $tw_gstem.a.$'cgi.style'+bak || 254 csaExit.fault 0003 cp 255 256 # Create work file only if not already created. 257 csaIsFullPath --quiet $gmux_tmp || csaMkTemp gmux_tmp 258 259 # Dump env vars and retain only the group-related ones. 260 # The set of alternate vars that are allowed is the same 261 # of the one at the group level. 262 { printf '\001var_name\t\001var_value\n' 263 envtotable | tabletolist --no-^(header footer unescape) --lists 264 } | sorttable | jointable $CSA_ROOT/lib/group-vars.dat | 265 tail -n +2 > $gmux_tmp 266 csaStatus || 267 csaExit.fault 0003 envtotable/tabletolist/sorttable/jointable/tail 268 269 # Pick allowed group-related vars from group.a.alt+mux. 270 { printf '\001var_name\t\001var_value\n' 271 muxtotable < $tw_gstem.a.$'cgi.style'+mux | 272 tabletolist --no-^(header footer unescape) --lists 273 } | sorttable | jointable $CSA_ROOT/lib/group-vars.dat | 274 tail -n +2 >> $gmux_tmp 275 csaStatus || 276 csaExit.fault 0003 envtotable/tabletolist/sorttable/jointable/tail 277 278 muxtotable < $gmux_tmp | csa-tbl2rc \ 279 --^(lists union no-count break prefix) ..NONE.. \ 280 > $tw_gstem.a.$'cgi.style'+cf 281 282 csaStatus || csaExit.fault 0003 muxtotable/csa-tbl2rc 283 284 . $tw_gstem.a.$'cgi.style'+cf # load the updated values. 285 } 286 287 # Release PLS ASAP. 288 csaUnlock $CSA_ROOT/var/pages/$CSA_LANG/group+dat 289 } 290 } 291 292 . $tw_gstem+cod # run extra local code 293 294 # Load user-defined template vars if any. 295 csaIsFullPath --exists --quiet $tw_gstem+rc && . $tw_gstem+rc 296 } 297 298 # Override group meta-data with actual values (linear search is ok here). 299 csaMkTemp tmp1 300 csa-tbl2rc --input $CSA_ROOT/var/pages/$CSA_LANG/group+dat \ 301 --key $'cgi.group' --prefix tbl_group. > $tmp1 || 302 csaExit.fault 0003 csa-tbl2rc 303 304 . $tmp1 305 306 # A group MUST exist. It is up to each and every rpclib program to 307 # decide whether or not to load group-stuff.rc, based on either the 308 # existence of the target group or the lack thereof. In general, no 309 # rpclib programs except 'rpclib/showPage' should load group-stuff.rc 310 # if the requested group does not exist. 311 312 if (~ $'tbl_group.k_group' ()) { 313 csaIsInteractive || csaExit.fault 1010 $'cgi.group' 314 315 # New group, so I cannot rely upon group-level custom templates. 316 317 tw_dstem = $CSA_ROOT/lib/default 318 319 # Account for the fact that templates are created by the client. 320 CSA_TPL_SAFEPATH = ($CSA_INSTALL/lib $tw_dstem $TMPDIR $CSA_TPL_ROOT 321 $CSA_DOCROOT/$CSA_LANG/$TNS_ATTACH_PUBDIR) 322 323 CSA_EXIT_SCRIPT = $CSA_ROOT/lib/exit-stuff.rc 324 325 ~ $'cgi.group.literal' () && 326 cgi.group.literal = $'cgi.group' # just in case 327 328 # Set group-related template vars. 329 tpl.var.tw.group = $'cgi.group.literal' 330 tpl.var.tw.descr = $'cgi.group.literal' 331 tpl.if.tw.ispage = '(::DEL:)' 332 tpl.fi.tw.ispage = '(:DEL::)' 333 tpl.if.tw.printable = '(::DEL:)' 334 tpl.fi.tw.printable = '(:DEL::)' 335 tpl.if.tw.isview = () 336 tpl.fi.tw.isview = () 337 csaAssign TNS_GROUP_MISC_PROP $nil 2 338 339 # CSA_PGM($#CSA_PGM) is set to "showPage" at this point, because 340 # of the rewrite done by "lib/rest.map", so the response page 341 # title will be the one set by "lib/rpcio/showPage.awk", hence 342 # the next setting to get a somewhat meaningful page title. 343 344 tbl_group.g_descr = $'cgi.group.literal' 345 346 # Build the list of URLs to existing group names which sound 347 # like the missing one, in case the editor actually meant 348 # one of those. This should help with keeping things tidy. 349 350 csaMkTemp tpl.include.tw.page 351 352 * = `{echo $soh^groupname$nl$'cgi.group.literal' | soundex --no-header} 353 354 { 355 getcolumn --input \ 356 $CSA_ROOT/var/pages/$CSA_LANG/group+dat g_name g_uri | 357 soundex --soundex-column soundex_ 358 getcolumn --no-header --input \ 359 $CSA_ROOT/var/pages/$CSA_LANG/group+dat soundex_ g_name g_uri | 360 grep -i $tab.*$'cgi.group.literal' 361 } | sorttable -u g_name | 362 awktable -- 'BEGIN{ print "" }' > $'tpl.include.tw.page' 375 376 # New group; I cannot rely on group-level templates here, so I pick the 377 # relevant default in the local language if available, otherwise I go 378 # for the global default. 379 380 if (csaIsFullPath --exists --quiet \ 381 $tw_dstem/i18n/$CSA_LANG/tw-new-group.txt) { 382 tpl.include.html.body = $tw_dstem/i18n/$CSA_LANG/tw-new-group.txt 383 } else tpl.include.html.body = $tw_dstem/tw-new-group.txt 384 385 if (csaIsFullPath --exists --quiet \ 386 $tw_dstem/i18n/$CSA_LANG/tw.$CSA_TPLEXT) { 387 tpl_file = (--file-root $tw_dstem/i18n/$CSA_LANG tw.$CSA_TPLEXT) 388 } else tpl_file = (--file-root $tw_dstem tw.$CSA_TPLEXT) 389 390 # Load local language-specific default group settings. 391 csaIsFullPath --exists --quiet \ 392 $CSA_ROOT/var/pages/$CSA_LANG/tw-default+cf && 393 . $CSA_ROOT/var/pages/$CSA_LANG/tw-default+cf 394 395 csaExit.ok $tpl_file 396 } 397 398 # Set group template vars to their final values. 399 tpl.var.tw.group.unx = $'tbl_group.k_group' 400 tpl.var.tw.group = $'tbl_group.g_name' 401 402 # Set default page title. 403 tpl.var.html.title = $'tpl.var.tw.group' 404 405 # Picking the appropriate session box should be done before 406 # any error message other than 1000 an 1010 are issued. 407 408 if (csaTrue $CSA_AUTH_OK) { 409 tw_auth_box = logout 410 } else tw_auth_box = login 411 412 if (csaIsFullPath --exists --quiet $CSA_TPL_ROOT/tw-nav-$tw_auth_box.txt) { 413 # custom session box template. 414 tpl.include.nav.session = $CSA_TPL_ROOT/tw-nav-$tw_auth_box.txt 415 } else { 416 # default session box template. 417 tpl.include.nav.session = $tw_dstem/tw-nav-$tw_auth_box.txt 418 } 419 420 # Pick local fault/ok CSA message templates if available. 421 tw_stem = $CSA_DOCROOT/$CSA_LANG/$TNS_ATTACH_PUBDIR/$'cgi.group' 422 if (csaIsFullPath --exists --quiet $tw_stem/.tw.msg) { 423 tpl.include.tw.tpl.ok = $tw_stem/.tw.msg 424 tpl.include.tw.tpl.fault = $tw_stem/.tw.msg 425 } 426 427 # Make sure the user's preferred editing GUI, if any, is acceptable 428 # for this group, and override it if necessary. 429 430 TNS_ALLOW_GUI = ($TNS_ALLOW_GUI default) 431 432 # Set the actual GUI to the preferred one if possible. Unless 433 # TNS_HTML2WIKI_CMD points at a real syntax converter, there should not 434 # be editors using HTML-level GUIs and other editors using WIKI-style 435 # GUIs on the same TW group, as otherwise they would keep interefering 436 # with each-other, messing things up upon every new page edit. 437 438 # If TNS_ALLOW_GUI is empty this will never match, which is fine. 439 if (~ $CSA_SESSION(11) $TNS_ALLOW_GUI) { 440 TNS_USE_GUI = $CSA_SESSION(11) 441 } else TNS_USE_GUI = $TNS_ALLOW_GUI(1) 442 443 # Store the selected filter in a separate session cookie which is read 444 # by 'updatePage' and possibly others. 445 # 446 # While $CSA_SESSION(11) *may* contain the *preferred* GUI for this 447 # user, the "twfilter" cookie is used to pass the *actual* GUI from 448 # editPage to updatePage. This is only a courtesy setting, which tries 449 # to find a compromise between the preferred and the allowed GUI for 450 # the user's convenience, but it cannot be prescriptive as it is 451 # cookie-based and it can be defeated. The only actual prescriptive 452 # enforcement is the one performed by 'updatePage'. Setting the filter 453 # has proven to be especially tricky, because the user may be editing 454 # multiple pages in different groups or even different TW instances 455 # on the same server at the same time. Furthermore, even along the same 456 # edititng session, web paths may be built differently, with some of 457 # them that lack the TW group indication (think of the PRG URL). After 458 # many more or less complicated attempts, the only safe and simple 459 # solution that I found is to have the cookie set for the whole web 460 # server and contain both the CSA instance and the TW group name. 461 462 csaCookie.set twfilter_$CSA_ID^_$'cgi.group' $TNS_USE_GUI 463 464 #tns1 = () { 465 # 466 # # Avoid setting // in cookie path if CSA_RPC_FLAG is null. 467 # ~ $CSA_RPC_FLAG () || tns1 = $CSA_RPC_FLAG/ 468 # 469 # csaCookie.set twfilter $TNS_USE_GUI --domain $CSA_FQDN \ 470 # --path $CSA_CGI_STEM/$CSA_ID/$tns1$CSA_LANG/$'tbl_group.g_uri' 471 #} 472 473 # Check group required metadata. It is done here to take advantage 474 # of any custom error templates. 475 476 ~ $'cgi.group.literal' () && csaExit.fault 0041 cgi.group.literal 477 478 # Default group+cf created only if needed and only if global editor. 479 # Only at this stage all of the required variables are know. 480 481 if (~ ,$TNS_AUTH_GRP, *,editor,* && !~ $need_default ()) { 482 # Only editors have got all of the following variables 483 # correctly set. DO NOT create the file if not an editor! 484 # If no grup defaults are found, they are created based 485 # on those that are currently in effect. 486 { 487 echo 'TNS_GROUP_HOME=(''Home Page'' Home%20Page)' 488 echo 'TNS_LC_ALL=('$TNS_LC_ALL')' 489 echo 'TNS_ALLOW_GUI=('$^TNS_ALLOW_GUI')' 490 } > $CSA_ROOT/var/pages/$CSA_LANG/tw-default+cf || 491 csaExit.fault 0009 $CSA_ROOT/var/pages/$CSA_LANG/tw-default+cf 492 } 493 494 #EOF