[0001]
[0002]
[0003]
[0004]
[0005]
[0006]
[0007]
[0008]
[0009]
[0010]
[0011]
[0012]
[0013]
[0014]
[0015]
[0016]
[0017]
[0018]
[0019]
[0020]
[0021]
[0022]
[0023]
[0024]
[0025]
[0026]
[0027]
[0028]
[0029]
[0030]
[0031]
[0032]
[0033]
[0034]
[0035]
[0036]
[0037]
[0038]
[0039]
[0040]
[0041]
[0042]
[0043]
[0044]
[0045]
[0046]
[0047]
[0048]
[0049]
[0050]
[0051]
[0052]
[0053]
[0054]
[0055]
[0056]
[0057]
[0058]
[0059]
[0060]
[0061]
[0062]
[0063]
[0064]
[0065]
[0066]
[0067]
[0068]
[0069]
[0070]
[0071]
[0072]
[0073]
[0074]
[0075]
[0076]
[0077]
[0078]
[0079]
[0080]
[0081]
[0082]
[0083]
[0084]
[0085]
[0086]
[0087]
[0088]
[0089]
[0090]
[0091]
[0092]
[0093]
[0094]
[0095]
[0096]
[0097]
[0098]
[0099]
[0100]
[0101]
[0102]
[0103]
[0104]
[0105]
[0106]
[0107]
[0108]
[0109]
[0110]
[0111]
[0112]
[0113]
[0114]
[0115]
[0116]
[0117]
[0118]
[0119]
[0120]
[0121]
[0122]
[0123]
[0124]
[0125]
[0126]
[0127]
[0128]
[0129]
[0130]
[0131]
[0132]
[0133]
[0134]
[0135]
[0136]
[0137]
[0138]
[0139]
[0140]
[0141]
[0142]
[0143]
[0144]
[0145]
[0146]
[0147]
[0148]
[0149]
[0150]
[0151]
[0152]
[0153]
[0154]
[0155]
[0156]
[0157]
[0158]
[0159]
[0160]
[0161]
[0162]
[0163]
[0164]
[0165]
[0166]
[0167]
[0168]
[0169]
[0170]
[0171]
[0172]
[0173]
[0174]
[0175]
[0176]
[0177]
[0178]
[0179]
[0180]
[0181]
[0182]
[0183]
[0184]
[0185]
[0186]
[0187]
[0188]
[0189]
[0190]
[0191]
[0192]
[0193]
[0194]
[0195]
[0196]
[0197]
[0198]
[0199]
[0200]
[0201]
[0202]
[0203]
[0204]
[0205]
[0206]
[0207]
[0208]
[0209]
[0210]
[0211]
[0212]
[0213]
[0214]
[0215]
[0216]
[0217]
[0218]
[0219]
[0220]
[0221]
[0222]
[0223]
[0224]
[0225]
[0226]
[0227]
[0228]
[0229]
[0230]
[0231]
[0232]
[0233]
[0234]
[0235]
[0236]
[0237]
[0238]
[0239]
[0240]
[0241]
[0242]
[0243]
[0244]
[0245]
[0246]
[0247]
[0248]
[0249]
[0250]
[0251]
[0252]
[0253]
[0254]
[0255]
[0256]
[0257]
[0258]
[0259]
[0260]
[0261]
[0262]
[0263]
[0264]
[0265]
[0266]
[0267]
[0268]
[0269]
[0270]
[0271]
[0272]
[0273]
[0274]
[0275]
[0276]
[0277]
[0278]
[0279]
[0280]
[0281]
[0282]
[0283]
[0284]
[0285]
[0286]
[0287]
[0288]
[0289]
[0290]
[0291]
[0292]
[0293]
[0294]
[0295]
[0296]
[0297]
[0298]
[0299]
[0300]
[0301]
[0302]
[0303]
[0304]
[0305]
[0306]
[0307]
[0308]
[0309]
[0310]
[0311]
[0312]
[0313]
[0314]
[0315]
[0316]
[0317]
[0318]
[0319]
[0320]
[0321]
[0322]
[0323]
[0324]
[0325]
[0326]
[0327]
[0328]
[0329]
[0330]
[0331]
[0332]
[0333]
[0334]
[0335]
[0336]
[0337]
[0338]
[0339]
[0340]
[0341]
[0342]
[0343]
[0344]
[0345]
[0346]
[0347]
[0348]
[0349]
[0350]
[0351]
[0352]
[0353]
[0354]
[0355]
[0356]
[0357]
[0358]
[0359]
[0360]
[0361]
[0362]
[0363]
[0364]
[0365]
[0366]
[0367]
[0368]
[0369]
[0370]
[0371]
[0372]
[0373]
[0374]
[0375]
[0376]
[0377]
[0378]
[0379]
[0380]
[0381]
[0382]
[0383]
[0384]
[0385]
[0386]
[0387]
[0388]
[0389]
[0390]
[0391]
[0392]
[0393]
[0394]
[0395]
[0396]
[0397]
[0398]
[0399]
[0400]
[0401]
[0402]
[0403]
[0404]
[0405]
[0406]
[0407]
[0408]
[0409]
[0410]
[0411]
[0412]
[0413]
[0414]
[0415]
[0416]
[0417]
[0418]
[0419]
[0420]
[0421]
[0422]
[0423]
[0424]
[0425]
[0426]
[0427]
[0428]
[0429]
[0430]
[0431]
[0432]
[0433]
[0434]
[0435]
[0436]
[0437]
[0438]
[0439]
[0440]
[0441]
[0442]
[0443]
[0444]
[0445]
[0446]
[0447]
[0448]
[0449]
[0450]
[0451]
[0452]
[0453]
[0454]
[0455]
[0456]
[0457]
[0458]
[0459]
[0460]
[0461]
[0462]
[0463]
[0464]
[0465]
[0466]
[0467]
[0468]
[0469]
[0470]
[0471]
[0472]
[0473]
[0474]
[0475]
[0476]
[0477]
[0478]
[0479]
[0480]
[0481]
[0482]
[0483]
[0484]
[0485]
[0486]
[0487]
[0488]
[0489]
[0490]
[0491]
[0492]
[0493]
[0494]
[0495]
[0496]
[0497]
[0498]
[0499]
[0500]
[0501]
[0502]
[0503]
[0504]
[0505]
[0506]
[0507]
[0508]
[0509]
[0510]
[0511]
[0512]
[0513]
[0514]
[0515]
[0516]
[0517]
[0518]
[0519]
[0520]
[0521]
[0522]
[0523]
[0524]
[0525]
[0526]
[0527]
[0528]
[0529]
[0530]
[0531]
[0532]
[0533]
[0534]
[0535]
[0536]
[0537]
[0538]
[0539]
[0540]
[0541]
[0542]
[0543]
[0544]
[0545]
[0546]
[0547]
[0548]
[0549]
[0550]
[0551]
[0552]
[0553]
[0554]
[0555]
[0556]
[0557]
[0558]
[0559]
[0560]
[0561]
[0562]
[0563]
[0564]
[0565]
[0566]
[0567]
[0568]
[0569]
[0570]
[0571]
[0572]
[0573]
[0574]
[0575]
[0576]
[0577]
[0578]
[0579]
[0580]
[0581]
[0582]
[0583]
[0584]
[0585]
[0586]
[0587]
[0588]
[0589]
[0590]
[0591]
[0592]
[0593]
[0594]
[0595]
[0596]
[0597]
[0598]
[0599]
[0600]
[0601]
[0602]
[0603]
[0604]
[0605]
[0606]
[0607]
[0608]
[0609]
[0610]
[0611]
[0612]
[0613]
[0614]
[0615]
[0616]
[0617]
[0618]
[0619]
[0620]
[0621]
[0622]
[0623]
[0624]
[0625]
[0626]
[0627]
[0628]
[0629]
[0630]
[0631]
[0632]
[0633]
[0634]
[0635]
[0636]
[0637]
[0638]
[0639]
[0640]
[0641]
[0642]
[0643]
[0644]
[0645]
[0646]
[0647]
[0648]
[0649]
[0650]
[0651]
[0652]
[0653]
[0654]
[0655]
[0656]
[0657]
[0658]
[0659]
[0660]
[0661]
[0662]
[0663]
[0664]
[0665]
[0666]
[0667]
[0668]
[0669]
[0670]
[0671]
[0672]
[0673]
[0674]
[0675]
[0676]
[0677]
[0678]
[0679]
[0680]
[0681]
[0682]
[0683]
[0684]
[0685]
[0686]
[0687]
[0688]
[0689]
[0690]
[0691]
[0692]
[0693]
[0694]
[0695]
[0696]
[0697]
[0698]
[0699]
[0700]
[0701]
[0702]
[0703]
[0704]
[0705]
[0706]
[0707]
[0708]
[0709]
[0710]
[0711]
[0712]
[0713]
[0714]
[0715]
[0716]
[0717]
[0718]
[0719]
[0720]
[0721]
[0722]
[0723]
[0724]
[0725]
[0726]
[0727]
[0728]
[0729]
[0730]
[0731]
[0732]
[0733]
[0734]
[0735]
[0736]
[0737]
[0738]
[0739]
[0740]
[0741]
[0742]
[0743]
[0744]
[0745]
[0746]
[0747]
[0748]
[0749]
[0750]
[0751]
[0752]
[0753]
[0754]
[0755]
[0756]
[0757]
[0758]
[0759]
[0760]
[0761]
[0762]
[0763]
[0764]
[0765]
[0766]
[0767]
[0768]
[0769]
[0770]
[0771]
[0772]
[0773]
[0774]
[0775]
[0776]
[0777]
[0778]
[0779]
[0780]
[0781]
[0782]
[0783]
[0784]
[0785]
[0786]
[0787]
[0788]
[0789]
[0790]
[0791]
[0792]
[0793]
[0794]
[0795]
[0796]
[0797]
[0798]
[0799]
[0800]
[0801]
[0802]
[0803]
[0804]
[0805]
[0806]
[0807]
[0808]
[0809]
[0810]
[0811]
[0812]
[0813]
[0814]
[0815]
[0816]
[0817]
[0818]
[0819]
[0820]
[0821]
[0822]
[0823]
[0824]
[0825]
[0826]
[0827]
[0828]
[0829]
[0830]
[0831]
[0832]
[0833]
[0834]
[0835]
[0836]
[0837]
[0838]
[0839]
[0840]
[0841]
[0842]
[0843]
[0844]
[0845]
[0846]
[0847]
[0848]
[0849]
[0850]
[0851]
[0852]
[0853]
[0854]
[0855]
[0856]
[0857]
[0858]
[0859]
[0860]
[0861]
[0862]
[0863]
[0864]
[0865]
[0866]
[0867]
[0868]
[0869]
[0870]
[0871]
[0872]
[0873]
[0874]
[0875]
[0876]
[0877]
[0878]
[0879]
[0880]
[0881]
[0882]
[0883]
[0884]
[0885]
[0886]
[0887]
[0888]
[0889]
[0890]
[0891]
[0892]
[0893]
[0894]
[0895]
[0896]
[0897]
[0898]
[0899]
[0900]
[0901]
[0902]
[0903]
[0904]
[0905]
[0906]
[0907]
[0908]
[0909]
[0910]
[0911]
[0912]
[0913]
[0914]
[0915]
[0916]
[0917]
[0918]
[0919]
[0920]
[0921]
[0922]
[0923]
[0924]
[0925]
[0926]
[0927]
[0928]
[0929]
[0930]
[0931]
[0932]
[0933]
[0934]
[0935]
[0936]
[0937]
[0938]
[0939]
[0940]
[0941]
[0942]
[0943]
[0944]
[0945]
[0946]
[0947]
[0948]
[0949]
[0950]
[0951]
[0952]
[0953]
[0954]
[0955]
[0956]
[0957]
[0958]
[0959]
[0960]
[0961]
[0962]
[0963]
[0964]
[0965]
[0966]
[0967]
[0968]
[0969]
[0970]
[0971]
[0972]
[0973]
[0974]
[0975]
[0976]
[0977]
[0978]
[0979]
[0980]
[0981]
[0982]
[0983]
[0984]
[0985]
[0986]
[0987]
[0988]
[0989]
[0990]
[0991]
[0992]
[0993]
[0994]
[0995]
[0996]
[0997]
[0998]
[0999]
[1000]
[1001]
[1002]
[1003]
[1004]
[1005]
[1006]
[1007]
[1008]
[1009]
[1010]
[1011]
[1012]
[1013]
[1014]
[1015]
[1016]
[1017]
[1018]
[1019]
[1020]
[1021]
[1022]
[1023]
[1024]
[1025]
[1026]
[1027]
[1028]
[1029]
[1030]
[1031]
[1032]
[1033]
[1034]
[1035]
[1036]
[1037]
[1038]
[1039]
[1040]
[1041]
[1042]
[1043]
[1044]
[1045]
[1046]
[1047]
[1048]
[1049]
[1050]
[1051]
[1052]
[1053]
[1054]
[1055]
[1056]
[1057]
[1058]
[1059]
[1060]
[1061]
[1062]
[1063]
[1064]
[1065]
[1066]
[1067]
[1068]
[1069]
[1070]
[1071]
[1072]
[1073]
[1074]
[1075]
[1076]
[1077]
[1078]
[1079]
[1080]
[1081]
[1082]
[1083]
[1084]
[1085]
[1086]
[1087]
[1088]
[1089]
[1090]
[1091]
[1092]
[1093]
[1094]
[1095]
[1096]
[1097]
[1098]
[1099]
[1100]
[1101]
[1102]
[1103]
[1104]
[1105]
[1106]
[1107]
[1108]
[1109]
[1110]
[1111]
[1112]
[1113]
[1114]
[1115]
[1116]
[1117]
[1118]
[1119]
[1120]
[1121]
[1122]
[1123]
[1124]
[1125]
[1126]
[1127]
[1128]
[1129]
[1130]
[1131]
[1132]
[1133]
[1134]
[1135]
[1136]
[1137]
[1138]
[1139]
[1140]
[1141]
[1142]
[1143]
[1144]
[1145]
[1146]
[1147]
[1148]
[1149]
[1150]
[1151]
[1152]
[1153]
[1154]
[1155]
[1156]
[1157]
[1158]
[1159]
[1160]
[1161]
[1162]
[1163]
[1164]
[1165]
[1166]
[1167]
[1168]
[1169]
[1170]
[1171]
[1172]
[1173]
[1174]
[1175]
[1176]
[1177]
[1178]
[1179]
[1180]
[1181]
[1182]
[1183]
[1184]
[1185]
[1186]
[1187]
[1188]
[1189]
[1190]
[1191]
[1192]
[1193]
[1194]
[1195]
[1196]
[1197]
[1198]
[1199]
[1200]
[1201]
[1202]
[1203]
[1204]
[1205]
[1206]
[1207]
[1208]
[1209]
[1210]
[1211]
[1212]
[1213]
[1214]
[1215]
[1216]
[1217]
[1218]
[1219]
[1220]
[1221]
[1222]
[1223]
[1224]
[1225]
[1226]
[1227]
[1228]
[1229]
[1230]
[1231]
[1232]
[1233]
[1234]
[1235]
[1236]
[1237]
[1238]
[1239]
[1240]
[1241]
[1242]
[1243]
[1244]
[1245]
[1246]
[1247]
[1248]
[1249]
[1250]
[1251]
[1252]
[1253]
[1254]
[1255]
[1256]
[1257]
[1258]
[1259]
[1260]
[1261]
[1262]
[1263]
[1264]
[1265]
[1266]
[1267]
[1268]
[1269]
[1270]
[1271]
[1272]
[1273]
[1274]
[1275]
[1276]
[1277]
[1278]
[1279]
[1280]
[1281]
[1282]
[1283]
[1284]
[1285]
[1286]
[1287]
[1288]
[1289]
[1290]
[1291]
[1292]
[1293]
[1294]
[1295]
[1296]
[1297]
[1298]
[1299]
[1300]
[1301]
[1302]
[1303]
[1304]
[1305]
[1306]
[1307]
[1308]
[1309]
[1310]
[1311]
[1312]
[1313]
[1314]
[1315]
[1316]
[1317]
[1318]
[1319]
[1320]
[1321]
[1322]
[1323]
[1324]
[1325]
[1326]
[1327]
[1328]
[1329]
[1330]
[1331]
[1332]
[1333]
[1334]
[1335]
[1336]
[1337]
[1338]
[1339]
[1340]
[1341]
[1342]
[1343]
[1344]
[1345]
[1346]
[1347]
[1348]
[1349]
[1350]
[1351]
[1352]
[1353]
[1354]
[1355]
[1356]
[1357]
[1358]
[1359]
[1360]
[1361]
[1362]
[1363]
[1364]
[1365]
[1366]
[1367]
[1368]
[1369]
[1370]
[1371]
[1372]
[1373]
[1374]
[1375]
[1376]
[1377]
[1378]
[1379]
[1380]
[1381]
[1382]
[1383]
[1384]
[1385]
[1386]
[1387]
[1388]
[1389]
[1390]
[1391]
[1392]
[1393]
[1394]
[1395]
[1396]
[1397]
[1398]
[1399]
[1400]
[1401]
[1402]
[1403]
[1404]
[1405]
[1406]
[1407]
[1408]
[1409]
[1410]
[1411]
[1412]
[1413]
[1414]
[1415]
[1416]
[1417]
[1418]
[1419]
[1420]
[1421]
[1422]
[1423]
[1424]
[1425]
[1426]
[1427]
[1428]
[1429]
[1430]
[1431]
[1432]
[1433]
[1434]
[1435]
[1436]
[1437]
[1438]
[1439]
[1440]
[1441]
[1442]
[1443]
[1444]
[1445]
[1446]
[1447]
[1448]
[1449]
[1450]
[1451]
[1452]
[1453]
[1454]
[1455]
[1456]
[1457]
[1458]
[1459]
[1460]
[1461]
[1462]
[1463]
[1464]
[1465]
[1466]
[1467]
[1468]
[1469]
[1470]
[1471]
[1472]
[1473]
[1474]
[1475]
[1476]
[1477]
[1478]
[1479]
[1480]
[1481]
[1482]
[1483]
[1484]
[1485]
[1486]
[1487]
[1488]
[1489]
[1490]
[1491]
[1492]
[1493]
[1494]
[1495]
[1496]
[1497]
[1498]
[1499]
[1500]
[1501]
[1502]
[1503]
[1504]
[1505]
[1506]
[1507]
[1508]
[1509]
[1510]
[1511]
[1512]
[1513]
[1514]
[1515]
[1516]
[1517]
[1518]
[1519]
[1520]
[1521]
[1522]
[1523]
[1524]
[1525]
[1526]
[1527]
[1528]
[1529]
[1530]
[1531]
[1532]
[1533]
[1534]
[1535]
[1536]
[1537]
[1538]
[1539]
[1540]
[1541]
[1542]
[1543]
[1544]
[1545]
[1546]
[1547]
[1548]
[1549]
[1550]
[1551]
[1552]
[1553]
[1554]
[1555]
[1556]
[1557]
[1558]
[1559]
[1560]
[1561]
[1562]
[1563]
[1564]
[1565]
[1566]
[1567]
[1568]
[1569]
[1570]
[1571]
[1572]
[1573]
[1574]
[1575]
[1576]
[1577]
[1578]
[1579]
[1580]
[1581]
[1582]
[1583]
[1584]
[1585]
[1586]
[1587]
[1588]
[1589]
[1590]
[1591]
[1592]
[1593]
[1594]
[1595]
[1596]
[1597]
[1598]
[1599]
[1600]
[1601]
[1602]
[1603]
[1604]
[1605]
[1606]
[1607]
[1608]
[1609]
[1610]
[1611]
[1612]
[1613]
[1614]
[1615]
[1616]
[1617]
[1618]
[1619]
[1620]
[1621]
[1622]
[1623]
[1624]
[1625]
[1626]
[1627]
[1628]
[1629]
[1630]
[1631]
[1632]
[1633]
[1634]
[1635]
[1636]
[1637]
[1638]
[1639]
[1640]
[1641]
[1642]
[1643]
[1644]
[1645]
[1646]
[1647]
[1648]
[1649]
[1650]
[1651]
[1652]
[1653]
[1654]
[1655]
[1656]
[1657]
[1658]
[1659]
[1660]
[1661]
[1662]
[1663]
[1664]
[1665]
[1666]
[1667]
[1668]
[1669]
[1670]
[1671]
[1672]
[1673]
[1674]
[1675]
[1676]
[1677]
[1678]
[1679]
[1680]
[1681]
[1682]
[1683]
[1684]
[1685]
[1686]
[1687]
[1688]
[1689]
[1690]
[1691]
[1692]
[1693]
[1694]
[1695]
[1696]
[1697]
[1698]
[1699]
[1700]
[1701]
[1702]
[1703]
[1704]
[1705]
[1706]
[1707]
[1708]
[1709]
[1710]
[1711]
[1712]
[1713]
[1714]
[1715]
[1716]
[1717]
[1718]
[1719]
[1720]
[1721]
[1722]
[1723]
[1724]
[1725]
[1726]
[1727]
[1728]
[1729]
[1730]
[1731]
[1732]
[1733]
[1734]
[1735]
[1736]
[1737]
[1738]
[1739]
[1740]
[1741]
[1742]
[1743]
[1744]
[1745]
[1746]
[1747]
[1748]
[1749]
[1750]
[1751]
[1752]
[1753]
[1754]
[1755]
[1756]
[1757]
[1758]
[1759]
[1760]
[1761]
[1762]
[1763]
[1764]
[1765]
[1766]
[1767]
[1768]
[1769]
[1770]
[1771]
[1772]
[1773]
[1774]
[1775]
[1776]
[1777]
[1778]
[1779]
[1780]
[1781]
[1782]
[1783]
[1784]
[1785]
[1786]
[1787]
[1788]
[1789]
[1790]
[1791]
[1792]
[1793]
[1794]
[1795]
[1796]
[1797]
[1798]
[1799]
[1800]
[1801]
[1802]
[1803]
[1804]
[1805]
[1806]
[1807]
[1808]
[1809]
[1810]
[1811]
[1812]
[1813]
[1814]
[1815]
[1816]
[1817]
[1818]
[1819]
[1820]
[1821]
[1822]
[1823]
[1824]
[1825]
[1826]
[1827]
[1828]
[1829]
[1830]
[1831]
[1832]
[1833]
[1834]
[1835]
[1836]
[1837]
[1838]
[1839]
[1840]
[1841]
[1842]
[1843]
[1844]
[1845]
[1846]
[1847]
[1848]
[1849]
[1850]
[1851]
[1852]
[1853]
[1854]
[1855]
[1856]
[1857]
[1858]
[1859]
[1860]
[1861]
[1862]
[1863]
[1864]
[1865]
[1866]
[1867]
[1868]
[1869]
[1870]
<!DOCTYPE html>
<!-- WASDOC AXP-2.0.0 (CGILIB AXP-1.9.9) -->
<!-- wasDOC Copyright (C) 2019,2020 Mark G.Daniel - Apache-2.0 licenced -->
<!--  3-NOV-2021 02:57 -->
<noscript>NOTE: SOME FUNCTIONALITY EMPLOYS JAVASCRIPT</noscript>
<div id="erreport1" style="display:none;"></div>
<script>
function errorReport(string) {
   for (var cnt = 1; cnt <= 2; cnt++) {
      var err = document.getElementById('erreport'+cnt);
      err.style.display = 'block';
      err.innerHTML += string;
   }
}
</script>
<style type="text/css">
html { font-family: arial, verdana, sans-serif; font-size:12pt; margin:1em; }
h1 { font-size:124%; font-style:bold;
     margin-top:1em; margin-bottom:0.5em; }
h2 { font-size:120%; font-style:bold;
     margin-top:1.1em; margin-bottom:0.4em; }
h3 { font-size:116%; font-style:bold;
     margin-top:1.0em; margin-bottom:0.3em; }
h4 { font-size:112%; font-style:bold;
     margin-top:1.1em; margin-bottom:0.3em; }
h5 { font-size:112%; font-style:bold; 
     margin-top:1.1em; margin-bottom:0.3em; }
h6 { font-size:112%; font-style:bold; padding:0; margin:0; }

h1 .text { text-decoration:underline; }
h1 .numb { padding-right:0.8em; }
h1 .numb:empty { display:none; padding-right:0; }
h2 .numb { padding-right:0.8em; }
h2 .numb:empty { display:none; padding-right:0; }
h3 .numb { padding-right:0.8em; }
h3 .numb:empty { display:none; padding-right:0; }
h4 .numb { padding-right:0.8em; }
h4 .numb:empty { display:none; padding-right:0; }
h5 .numb { display:none; padding-right:0; }
h6 .numb { display:none; padding-right:0; }

kbd { font-family:monospace; }

noscript { font-size:1.2em; }

p { line-height:1.1em; margin-top:1em; margin-bottom:1em; }

.chunk { font-size:130%; text-decoration:underline; }
.head {}
.high {}
.bold { font-weight:bold; }
.center { text-align:center; }
.italic { font-style:italic; }
.left { text-align:left; }
.nowrap { white-space:nowrap; }
.prewrap { white-space:pre; }
.right { text-align:right; }
.strike { text-decoration:line-through; }
.under { text-decoration:underline; }

.backlight { background-color:#f2f2f2; }
.display0 { display:none; }

img { max-width:100%; }
.imglink { }

.link { }
.blank { }

.list { margin-bottom:1em; }
.list li { margin-top:0.5em; }
.list0 li { margin-top:0; }
.item {}

.tabl { border-collapse:collapse; text-align:left; margin:0.4em 2em 0.5em 2em; }
.tabu { border-collapse:collapse; text-align:right; margin:0.4em 2em 0.5em 2em; }

.tabr { vertical-align:top; }
.tabh { padding:0.2em 0 0 2em; margin:0; }
.tabd { padding:0.1em 0 0 2em; margin:0; }
.tabh:first-of-type, td:first-of-type { padding-left:0; }

.tabu .tabh,
.tabu .tabd { border:1px solid gray; padding:0.2em 0.3em 0.2em 0.3em; }
.tab0 { border:none; visibility:hidden; max-width:1em; 
        white-space:nowrap; overflow:hidden; }

.tabauto { margin-left:auto; margin-right:auto; }

.tabr:empty { height:0.2em; }
.tabu .tabh:empty, .tabu .tabd:empty { border:none; visibility:hidden; }

.error { font-size:110%; color:black; background-color:yellow;
         font-family:sans-serif; font-weight:bold; font-style:normal;
         width:95%; border:solid 1px gray; padding:0.5em 1em 0.5em 1em; }
.error::before { content:'\026a0\00a0'; }
.image { }
.page { width:98%; border:1px dashed gray; margin:1.5em 0 1.8em 0; }
.epage { width:98%; border:1px dashed black; margin:1.5em 0 1.8em 0; }
.monosp { font-family:monospace; }
.ppage { display:none; }
.simple { list-style-type:none; }
.valtop { vertical-align:top; }
.valmid { vertical-align:middle; }
.valbot { vertical-align:bottom; }

.code { border-style:solid; border-width:0 0 0 1px; padding-left:1em;
        font-family:monospace; white-space:pre; }
.block { }
.blockof { margin:0.4em 2em 0.5em 2em; }
.example { border-style:dashed; border-width:0 0 0 1px; padding-left:1em;
           margin-top:0.5em; margin-bottom:0.5em; white-space:pre; }
.indent { margin-left:2em; margin-right:2em; }
.noindent { margin-left:0; margin-right:0; }
.inblock { display:inline-block; }
.mono { white-space:pre; font-family:monospace; }
.note { margin:0.4em 2em 0.5em 2em; page-break-inside:avoid; }
.note h5 { margin-top:0 }
.note_hr { width:80%; border:1px solid gray; }
.prop { padding-left:1em; margin-top:0.5em; margin-bottom:0.5em; }
.quote { border-style:dashed; border-width:0 0 0 1px; padding-left:1em;
         margin-top:0.5em; margin-bottom:0.5em; }
.this { display:none; }

a:link,a:visited { color:black; text-decoration:none; }
a:hover,a:active { text-decoration:underline; }
a:focus { outline:0; } 

:target:before { content:''; display:block; height:0.1em; margin:-0.1em; }
a.link:link, a.link:visited,a.link:active 
{ color:midnightBlue; text-decoration:underline; text-decoration-style:solid; }

.TOC1cols1 { width:80%; max-width:80%; }
.TOC1cols2 { column-count:2; width:80%; max-width:80%; }
.TOC1cols3 { column-count:3; max-width:90%; max-width:90%; }
.TOC1cols4 { column-count:4; max-width:100%; max-width:100%; }
.TOC1table { margin-left:2em; white-space:nowrap; break-inside:auto; }
.TOC1table tr { vertical-align:top; text-align:left; break-inside:avoid; break-after:auto; }
.TOC1table td+td { padding:0 0 0 0.5em; }
.TOC1table .numb { width:3em; max-width:3em; }
.TOC1table .sepr { width:5em; max-width:6em; overflow:hidden; }
.TOC1table .majr { font-weight:bold; }
.TOC1table .text { white-space:normal; }

/* These are due to Firefox (at least <= 76) recalcitrant multi-column handling.
   Web search "Split table into css columns, issue in Firefox" (stackoverflow).
   "Good grief, Charlie Brown!" */
 
.TOC1cols2 table,
.TOC1cols2 tbody,
.TOC1cols2 tr,
.TOC1cols3 table,
.TOC1cols3 tbody,
.TOC1cols3 tr,
.TOC1cols4 table,
.TOC1cols4 tbody,
.TOC1cols4 tr { display:block; padding:0; }

.TOC2cols1 { width:60%; max-width:60%; }
.TOC2cols2 { column-count:2; width:70%; max-width:70%; }
.TOC2cols3 { column-count:3; width:80%; max-width:80%; }
.TOC2cols4 { column-count:4; width:90%; max-width:90%; }
.TOC2table { margin-left:2em; white-space:nowrap; break-inside:auto; }
.TOC2table tr { vertical-align:top; text-align:left; break-inside:avoid; break-after:auto; }
.TOC2table .numb { font-weight:bold; padding-right:0.5em; }
.TOC2table .text { width:100%; white-space:normal; }

/* see "recalcitrant" above */
.TOC2cols2 table,
.TOC2cols2 tbody,
.TOC2cols2 tr,
.TOC2cols3 table,
.TOC2cols3 tbody,
.TOC2cols3 tr,
.TOC2cols4 table,
.TOC2cols4 tbody,
.TOC2cols4 tr { display:block; padding:0; }

.NAVtable { margin:0.1em 0 0 2em; }
.NAVtable td { font-size:110%; font-weight:bold; padding:0; margin:0; }
.NAVtable a { padding:0 0.5em 0 0.5em; text-decoration:none; }

.IDXcols1 { width:80%; max-width:80%; }
.IDXcols2 { column-count:2; width:90%; max-width:90%; }
.IDXcols3 { column-count:3; width:95%; max-width:95%;  }
.IDXcols4 { column-count:4; width:100%; max-width:100%;  }
.IDXtable { margin:1em 0 1em 2em; white-space:nowrap; break-inside:auto; }
.IDXtable tr { vertical-align:top; text-align:left; break-inside:avoid; break-after:auto; }
.IDXtable .alpha { font-weight:bold; min-width:2em; }
.IDXtable .text  { width:100%; white-space:normal; }
.IDXtable .para:before { content:'\00b6\00a0'; }

/* see "recalcitrant" above */
.IDXcols2 table,
.IDXcols2 tbody,
.IDXcols2 tr,
.IDXcols3 table,
.IDXcols3 tbody,
.IDXcols3 tr,
.IDXcols4 table,
.IDXcols4 tbody,
.IDXcols4 tr { display:block; padding:0; }

.insight { background-color:cyan; font-family:monospace;
           padding:0 0.2em 0 0.2em; margin:0 0.2em 0 0.2em;
           font-size:100%; font-style:normal; font-weight:normal;
           text-decoration:none; }

.wasdoc { font-family: "Lucida Console", Monaco, monospace; 
          letter-spacing:-0.07em; }

@media screen { .blank::after { content:"\2924"; } 
                .print { display:none; }
}

@media print {
   table { page-break-inside:avoid; }
   .noprint { display:none; }
   .page { border:none; page-break-after: always; }
   .epage { display:none; }
   .ppage { page-break-after:always; }
   .NAVtable { display:none; }
   .NAVprint { display:block!important; }
}

@page { margin:2cm 1cm 2cm 1cm;  }
</style>
<!-- source:0000_SCRIPTING.WASDOC -->

<style type="text/css">._smiley::after { font-size:150%; vertical-align:middle; content:'\263a' }</style>
<style type="text/css">._frowny::after { font-size:150%; vertical-align:middle; content:'\2639' }</style>

<a id="0." href="#"></a>
<title>WASD Scripting Environment &ndash; Introduction</title>
<a id="1." href="#"></a>
<a id="1.introduction" href="#"></a>
<a id="introduction" href="#"></a>
<h1 class="head chunk">WASD Scripting Environment</h1>
<h1 class="head"><span class="numb">1.</span><span class="text">Introduction</span></h1>

<div class="TOC2cols2">
<table class="TOC2table">
<tr><td><a href="scripting001.html#1.1.scriptingaccounts"><span class="numb">1.1</span><span class="text">Scripting Accounts</span></a>
<tr><td><a href="scripting001.html#1.2.scriptingprocesses"><span class="numb">1.2</span><span class="text">Scripting Processes</span></a>
<tr><td><a href="scripting001.html#1.2.1.processmanagement"><span class="numb">1.2.1</span><span class="text">Process Management</span></a>
<tr><td><a href="scripting001.html#1.2.2.processnomenclature"><span class="numb">1.2.2</span><span class="text">Process Nomenclature</span></a>
<tr><td><a href="scripting001.html#1.2.3.processscripting"><span class="numb">1.2.3</span><span class="text">Process Scripting</span></a>
<tr><td><a href="scripting001.html#1.2.3.1.personascripting"><span class="numb">1.2.3.1</span><span class="text">Persona Scripting</span></a>
<tr><td><a href="scripting001.html#1.2.3.2.restrictingpersonascripting"><span class="numb">1.2.3.2</span><span class="text">Restricting Persona Scripting</span></a>
<tr><td><a href="scripting001.html#1.2.3.3.processpriorities"><span class="numb">1.2.3.3</span><span class="text">Process Priorities</span></a>
<tr><td><a href="scripting001.html#1.2.4.scriptprocessdefault"><span class="numb">1.2.4</span><span class="text">Script Process Default</span></a>
<tr><td><a href="scripting001.html#1.2.5.scriptprocessparsetype"><span class="numb">1.2.5</span><span class="text">Script Process Parse Type</span></a>
<tr><td><a href="scripting001.html#1.2.6.scriptprocessrundown"><span class="numb">1.2.6</span><span class="text">Script Process Run-Down</span></a>
<tr><td><a href="scripting001.html#1.2.7.clientrecalcitrance"><span class="numb">1.2.7</span><span class="text">Client Recalcitrance</span></a>
<tr><td><a href="scripting001.html#1.3.scriptproctor"><span class="numb">1.3</span><span class="text">Script Proctor</span></a>
<tr><td><a href="scripting001.html#1.4.cachingscriptoutput"><span class="numb">1.4</span><span class="text">Caching Script Output</span></a>
<tr><td><a href="scripting001.html#1.5.enablingascript"><span class="numb">1.5</span><span class="text">Enabling A Script</span></a>
<tr><td><a href="scripting001.html#1.6.scriptmapping"><span class="numb">1.6</span><span class="text">Script Mapping</span></a>
<tr><td><a href="scripting001.html#1.7.scriptruntime"><span class="numb">1.7</span><span class="text">Script Run-Time</span></a>
<tr><td><a href="scripting001.html#1.8.unixsyntax"><span class="numb">1.8</span><span class="text">Unix Syntax</span></a>
<tr><td><a href="scripting001.html#1.9.scriptinglogicals"><span class="numb">1.9</span><span class="text">Scripting Logicals</span></a>
<tr><td><a href="scripting001.html#1.10.scriptingscratchspace"><span class="numb">1.10</span><span class="text">Scripting Scratch Space</span></a>
<tr><td><a href="scripting001.html#1.11.dclprocessingofrequests"><span class="numb">1.11</span><span class="text">DCL Processing of Requests</span></a>
<tr><td><a href="scripting001.html#1.12.scriptingfunctionlibrary"><span class="numb">1.12</span><span class="text">Scripting Function Library</span></a>
<tr><td><a href="scripting001.html#1.13.scriptrequestedservergeneratederrorresponses"><span class="numb">1.13</span><span class="text">Script-Requested, Server-Generated Error Responses</span></a>
</table>
</div>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="scripting000.html#0.">&#8598;&#xFE0E;</a>
<td><a href="scripting000.html#0.">&#8593;&#xFE0E;</a>
<td><a href="scripting002.html#2.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<p> This document is <span class="high bold">not a general tutorial on authoring scripts</span>, CGI or any
other. A large number of references in the popular computing press covers all
aspects of this technology, usually quite comprehensively.  The information
here is about the specifics of scripting in the WASD environment, which is
generally very much like any other implementation, VMS or otherwise (although
there are always annoying idiosyncracies, see <a class="link" href="scripting002.html#2.4.cgifunctionlibrary">2.4 CGI Function Library</a> for a
partial solution to smoothing out some of these wrinkles for VMS environments).

<p> <span class="high italic">Scripts</span> are mechanisms for creating Web applications and services,
sending data to (and often receiving data from) a client, extending the
capabilities of the basic server.  Scripts execute in processes and accounts
separate from the actual HTTP server but under its control and interacting with
it.

<p> WASD manages a script's execution environment as an independent detached
process created and managed by the HTTP server.  By configuration a script also
can be executed in a process created using DECnet.  Originally, WASD scripted in
subprocesses but this is obsolete.  There is no analogue of the Apache loadable
module executed within the server process itself.

<p> WASD scripting can be deployed in a number of environments.  Other sections
cover the specifics of these.  Don't become bewildered or be put off by all
these apparent options, they are basically variations on a CGI theme.

<ul class="list simple list0">
<li class="item"> <a class="link" href="scripting002.html#2.cgi">2. CGI</a>
<li class="item"> <a class="link" href="scripting003.html#3.cgiplus">3. CGIplus</a>
<li class="item"> <a class="link" href="scripting004.html#4.runtimeenvironments">4. Run-Time Environments</a>
<li class="item"> <a class="link" href="scripting005.html#5.websocket">5. WebSocket</a>
<li class="item"> <a class="link" href="scripting006.html#6.cgicallouts">6. CGI Callouts</a>
<li class="item"> <a class="link" href="scripting007.html#7.isapi">7. ISAPI</a>
<li class="item"> <a class="link" href="scripting008.html#8.decnetamposu">8. DECnet &amp; OSU</a>
<li class="item"> <a class="link" href="scripting009.html#9.otherenvironments">9. Other Environments</a>
<li class="item"> <a class="link" href="scripting010.html#10.requestredaction">10. Request Redaction</a>
<li class="item"> <a class="link" href="scripting011.html#11.rawtcpipsocket">11. Raw TCP/IP Socket</a>
</ul>

<a id="1.1" href="#"></a>
<a id="1.1.scriptingaccounts" href="#"></a>
<a id="scriptingaccounts" href="#"></a>
<h2 class="head"><span class="numb">1.1</span><span class="text">Scripting Accounts</span></h2>

<p> It is strongly recommended to execute scripts in an account distinct from
that executing the server.  This minimises the risk of both unintentional and
malicious interference with server operation through either Inter-Process
Communication (IPC) or scripts manipulating files used by the server.

<p> The default WASD installation creates two such accounts, with distinct
UICs, usernames and default directory space.  The UICs and home areas can be
specified differently to the displayed defaults.  Nothing should be assumed or
read into the scripting account username &ndash; it's just a username.

<a id="1.1.0.0.1" href="#"></a>
<a id="1.1.defaultaccounts" href="#"></a>
<a id="defaultaccounts" href="#"></a>
<h5 class="head"><span class="text">Default Accounts</span></h5>
<table class="tabl">
<tr class="tabr under">
<th class="tabh">Username
<th class="tabh">UIC
<th class="tabh">Default
<th class="tabh">Description
<tr class="tabr">
<tr class="tabr">
<td class="tabd">HTTP&dollar;SERVER
<td class="tabd">[077,001]
<td class="tabd">WASD_ROOT:[HTTP&dollar;SERVER]
<td class="tabd">Server Account
<tr class="tabr">
<td class="tabd">HTTP&dollar;NOBODY
<td class="tabd">[076,001]
<td class="tabd">WASD_ROOT:[HTTP&dollar;NOBODY]
<td class="tabd">Scripting Account
</table>

<p> During startup the server checks for the existence of the default scripting
account and automatically configures  itself to use this for scripting.  If it
is not present it falls-back to using the server account.  Other account names
can be used if the startup procedures are modified accordingly.  The default
scripting username may be overridden using the /SCRIPT=AS=&lt;username&gt;
qualifier (see <a class="link blank" target="_blank" href="../install/#serverstartup">Server Startup</a> in <a class="link blank" target="_blank" href="../install/#0.">WASD Installation</a>). 
The default scripting account cannot be a member of the SYSTEM group and cannot
have any privilege other than NETMBX and TMPMBX (<a class="link" href="scripting001.html#1.2.3.1.privilegeduserscripting">&lsquo;Privileged User Scripting&rsquo; in 1.2.3.1 Persona Scripting</a> describes how to configure to allow this).

<p> Scripting under a separate account is not available with subprocess
scripting and is distinct from PERSONA scripting (even though it uses the same
mechanism, see below).

<a id="1.2" href="#"></a>
<a id="1.2.scriptingprocesses" href="#"></a>
<a id="scriptingprocesses" href="#"></a>
<h2 class="head"><span class="numb">1.2</span><span class="text">Scripting Processes</span></h2>

<p> Process creation under the VMS operating system is notoriously slow and
expensive. This is an inescapable overhead when scripting via child processes.
An obvious strategy is to avoid, at least as much as possible, the creation of
these processes.  The only way to do this is to share processes between
multiple scripts/requests, addressing the attendant complications of isolating
potential interactions between requests. These could occur through changes made
by any script to the process' enviroment. For VMS this involves symbol and
logical name creation, and files opened at the DCL level. In reality few
scripts need to make logical name changes and symbols are easily removed
between uses. DCL-opened files are a little more problematic, but again, in
reality most scripts doing file manipulation will be images.

<p> A reasonable assumption is that for almost all environments scripts can
quite safely share processes with <span class="high under">great</span> benefit to response
latency and system impact
(see <a class="link blank" target="_blank" href="../features/#serverperformance">Server Performance</a> of <a class="link blank" target="_blank" href="../features/#0.">WASD Features</a>)
for a table with some comparative performances). If the local environment
requires absolute script isolation for some reason then this
process-persistance may easily be disabled with a consequent trade-off on
performance.

<p> The term <span class="high italic">zombie</span> is used to describe processes when
persisting between uses (the reason should be obvious, they are neither
&quot;alive&quot; (processing a request) nor are they &quot;dead&quot; (deleted <span class="high monosp">:^)</span>
Zombie processes have a finite time to exist (<span class="high italic">non-</span>life-time?)
before they are automatically run-down (see below).  This keeps process clutter
on the system to a minimum.

<a id="1.2.1" href="#"></a>
<a id="1.2.1.processmanagement" href="#"></a>
<a id="processmanagement" href="#"></a>
<h3 class="head"><span class="numb">1.2.1</span><span class="text">Process Management</span></h3>

<p> Scripting processes are created on-demand, within configuration limits
and timeout periods.  There are no arbitrary limits, only system resource
limits, on the number of scripting processes.  WASD_CONFIG_GLOBAL directives
control the configuration limits of these (see
<a class="link blank" target="_blank" href="../config/#globalconfiguration">Global Configuration</a> of <a class="link blank" target="_blank" href="../config/#0.">WASD Configuration</a>).

<div class="blockof code">[DclHardLimit]  100
[DclSoftLimit]   90
[DclZombieLifeTime]  00:10:00
[DclCgiPlusLifeTime]  00:30:00
</div>
 Other configuration directives are discussed later in this chapter.

<a id="1.2.1.0.1" href="#"></a>
<a id="1.2.1.hardlimit" href="#"></a>
<a id="hardlimit" href="#"></a>
<h5 class="head"><span class="text">Hard Limit</span></h5>

<p> Scripting processes of all kinds (CGI, CGIplus and RTE) are created
on-demand up until [DclHardLimit] is reached.  If all scripting processes are
busy with requests at that limit then the server provides a 503 (too busy)
response.

<a id="1.2.1.0.2" href="#"></a>
<a id="1.2.1.softlimit" href="#"></a>
<a id="softlimit" href="#"></a>
<h5 class="head"><span class="text">Soft Limit</span></h5>

<p> If there are more than [DclSoftLimit] scripting processes then the
least-recently-used of any idle processes (those not currently processing a
request) are proactively run-down until the soft-limit is reached.  This
provides <span class="high italic">head-room</span> for the immediate creation of additional
scripting processes for new requests that cannot be satisfied from currently
instantiated processes.   Soft-limit should of course be configured less than
hard-limit (and if not WASD makes it that way).

<a id="1.2.1.0.3" href="#"></a>
<a id="1.2.1.lifetimes" href="#"></a>
<a id="lifetimes" href="#"></a>
<h5 class="head"><span class="text">Lifetimes</span></h5>

<p> Idle scripting processes (those not having been given a request to process)
are proactively run-down (see <a class="link" href="scripting001.html#1.2.6.scriptprocessrundown">1.2.6 Script Process Run-Down</a>) after configured
periods. 

<p> [DclZombieLifeTime] specifies the period in minutes a CGI scripting process
can remain idle.

<p> [DclCgiPlusLifeTime] specifies the period a CGIplus script (inside a
CGIplus scripting process) or a RTE process can remain idle.

<p> If requests being serviced by scripts drop to zero for a period (governed
by the above lifetimes) then eventually all scripting processes should be
run-down leaving only the server process.

<a id="1.2.2" href="#"></a>
<a id="1.2.2.processnomenclature" href="#"></a>
<a id="processnomenclature" href="#"></a>
<h3 class="head"><span class="numb">1.2.2</span><span class="text">Process Nomenclature</span></h3>

<p> Script process naming occurs with the intention of providing some obvious
indication of the activity of the process.

<p> During script process creation the name momentarily is seen using the schema
<span class="high monosp">WASD:80-1</span> ... <span class="high monosp">WASD:80-999</span> but quickly moves to <span class="high monosp">WASD:80-<span class="high italic">pid</span></span> where
<span class="high italic">pid</span> are four hex digits of the LSW of the process PID (essentially to ensure
uniqueness).

<ol class="list">

<li class="item"> If a <span class="high bold">plain CGI script</span> is activated the process name incorporates as
much of the script name as can be accomodated.

<br> So CGI script <span class="high monosp">/cgi-bin/cgi_symbols</span> during processing would have the
name &quot;<span class="high monosp">/cgi_symbo_<span class="high italic">pid</span></span>&quot;.

<li class="item"> Similarly, if a <span class="high bold">CGIplus script</span> is activated the script name is
incororated, but with the PID element separated using a <span class="high italic">plus</span> symbol.

<br> So the <span class="high italic">conan</span> script would appear &quot;<span class="high monosp">/conan+<span class="high italic">pid</span></span>&quot;.

<li class="item"> With a <span class="high bold">WebSocket script</span> the PID element is separated using a
<span class="high italic">tilde</span> symbol.

<br> So the <span class="high italic">ws_mouse</span> example script would appear &quot;<span class="high monosp">/ws_mouse~<span class="high italic">pid</span></span>&quot;.

<li class="item"> An <span class="high bold">RTE</span> has the <span class="high italic">RTE name</span> (not script name) incorporated with
the PID element separated using an <span class="high italic">equals</span> symbol.

<br> So the <span class="high italic">PERL</span> RTE would appear &quot;<span class="high monosp">/perlrte=<span class="high italic">pid</span></span>&quot;.

<li class="item"> Where a script process is directly executing <span class="high bold">CLI commands</span> the
underscore changes to a <span class="high italic">dollar</span> symbol, as in &quot;<span class="high monosp">WASD:80&dollar;<span class="high italic">pid</span></span>.

</ol>

<p> Historically, WASD scripting processes have been named sequentially
<span class="high monosp">WASD:80-1</span> ... <span class="high monosp">WASD:80-999</span>.  A script <span class="high italic">could</span> change that and it would
remain even if the process was reused for another script.  Now at conclusion of
script processing v12 reverts the name.

<p> The v12 schema may be disabled by defining the logical name
WASD_DCL_PRCNAM_PRE12 prior to server start.

<a id="1.2.3" href="#"></a>
<a id="1.2.3.processscripting" href="#"></a>
<a id="processscripting" href="#"></a>
<h3 class="head"><span class="numb">1.2.3</span><span class="text">Process Scripting</span></h3>

<p> The default is for WASD to execute scripts in detached processes created
and managed completely independently of the server process itself.  This offers
a significant number of advantages

<ul class="list list0">
<li class="item"> pooled quotas are not a consideration
<li class="item"> buggy scripts cannot directly affect the server process
<li class="item"> can be created with more appropriate process priorities
<li class="item"> can be executed under accounts different to that of the server
<li class="item"> allows secure but yet full-featured user scripting
<li class="item"> processes created through the full account login process
</ul>

<p> Creation of a process is expensive in terms of system resources and initial
invocation response latency (particularly if extensive login procedures are
required), but this quickly becomes negligable as most script processes are used
multiple times for successive scripts and/or requests.

<p> There is no WASD analogue of the Apache loadable module executed within the
server process itself.

<a id="1.2.3.0.1" href="#"></a>
<a id="1.2.3.processmanagement" href="#"></a>
<a id="processmanagement" href="#"></a>
<h5 class="head"><span class="text">Process Management</span></h5>

<p> With detached processes the server must explicitly ensure that each
scripting process is removed from the system during server shutdown (cf.
subprocesses where the VMS <span class="high italic">executive</span> provides that automatically).  This
is performed by the server exit handler.  With VMS it is possible to bypass the
exit handler (using a &dollar;DELPRC or the equivalent &dollar;STOP/ID= for instance),
making it possible for &quot;orphaned&quot; scripting processes to remain &ndash; and
potentially accumulate on the system!

<p> To address this possibility the server scans the system for
candidate processes during each startup.  These are identified by a
<span class="high italic">terminal</span> mailbox (SYS&dollar;COMMAND device), and then further that the
mailbox has an ACL with two entries; the first identifying itself as a WASD
HTTPd mailbox and the second allowing access to the account the script is being
executed under.  Such a device ACL looks like the following example.

<div class="blockof code">Device MBA335:, device type local memory mailbox, is online, record-oriented
  device, shareable, mailbox device.

  Error count                    0    Operations completed                  0
  Owner process                 &quot;&quot;    Owner UIC             [WEB,HTTP&dollar;NOBODY]
  Owner process ID        00000000    Dev Prot              S:RWPL,O:RWPL,G,W
  Reference count                1    Default buffer size                2048
  Device access control list:
    (IDENTIFIER=WASD_HTTPD_80,ACCESS=NONE)
    (IDENTIFIER=[WEB,HTTP&dollar;NOBODY],ACCESS=READ+WRITE+PHYSICAL+LOGICAL)
</div>

<p> This rights identifier is generated from the server process name and is
therefore system-unique (so multiple autonomous servers will not accidentally
cleanup the script processes of others), and <span class="high bold">is created  during
server startup</span> if it does not already exist.  For example, if the process
name was &quot;HTTPd:80&quot; (the default for a standard service) the rights
identifier name would be &quot;WASD_HTTPD_80&quot; (as shown in the example
above).

<a id="1.2.3.0.2" href="#"></a>
<a id="1.2.3.syloginandloginprocedures" href="#"></a>
<a id="syloginandloginprocedures" href="#"></a>
<h5 class="head"><span class="text">SYLOGIN and LOGIN Procedures</span></h5>

<p> Scripting processes are created through the full &quot;LOGINOUT&quot; life-cycle and
execute all system and account LOGIN procedures.  Although immune to the effects
of most actions within these procedures, and absorbing any output generated
during this phase of the process life-cycle, some consideration should be given
to minimising the LOGIN procedure paths.  This can noticably reduce initial
script latency on less powerful platforms.

<p> The usual recommendations for non-interactive LOGIN procedures apply for
script environments as well.  Avoid interactive-only commands and reduce
unnecessary interactive process environment setup.  This is usually
accomplished though code structures such as the following

<div class="blockof code">&dollar; IF F&dollar;MODE() .EQS. &quot;INTERACTIVE&quot;
&dollar; THEN
     &hellip;
&dollar; ENDIF

&dollar; IF F&dollar;MODE() .NES. &quot;INTERACTIVE&quot; THEN EXIT
</div>

<p> WASD scripting processes can be specifically detected using DCL tests
similar to the following.  This checks the mode, that standard output is a
mailbox, and the process name.  These are fairly reliable (but not absolutely
infallible) indicators.

<div class="blockof code">&dollar; IF F&dollar;MODE() .NES. &quot;INTERACTIVE&quot; .AND. -
     F&dollar;GETDVI(&quot;SYS&dollar;OUTPUT&quot;,&quot;MBX&quot;) .AND. -
     F&dollar;EXTRACT(0,4,F&dollar;PROCESS()) .EQS. &quot;WASD&quot; .AND. -
     F&dollar;EXTRACT(5,1,F&dollar;PROCESS()) .EQS. &quot;:&quot; .AND. -
     F&dollar;ELEMENT(1,&quot;-&quot;,F&dollar;PROCESS()) .NES. &quot;-&quot;
&dollar; THEN
&dollar;!   WASD scripting process!
     &hellip;
&dollar; ENDIF
</div>

<a id="1.2.3.1" href="#"></a>
<a id="1.2.3.1.personascripting" href="#"></a>
<a id="personascripting" href="#"></a>
<h4 class="head"><span class="numb">1.2.3.1</span><span class="text">Persona Scripting</span></h4>

<p> There are advantages in running a script under a non-server account.  The
most obvious of these is the security isolation it offers with respect to the
rest of the Web and server environment.  It also means that the server account
does not need to be resourced especially for any particularly demanding
application.

<a id="1.2.3.1.1" href="#"></a>
<a id="1.2.3.1.enablingpersonascripting" href="#"></a>
<a id="enablingpersonascripting" href="#"></a>
<h5 class="head"><span class="text">Enabling Persona Scripting</span></h5>

<p> The &dollar;PERSONA functionality must be explicitly enabled at server startup
using the /PERSONA qualifier
(<a class="link blank" target="_blank" href="../install/#serveraccountandenvironment">Server Account and Environment</a> of <a class="link blank" target="_blank" href="../install/#0.">WASD Installation</a>). 
The ability for the server to be able to execute scripts under any user
account is a very powerful (and potentially dangerous) capability, and so is
designed that the site administrator must explicitly and deliberately enable
the functionality.  Configuration files need to be rigorously protected against
unauthorized modification.

<p> A specific script or directory of scripts can be designated for execution
under a specified account using the WASD_CONFIG_MAP configuration file
<span class="high italic">set script=as=</span> mapping rule.  The following example illustrates the
essentials.

<div class="blockof code"># one script to be executed under the account
SET  /cgi-bin/a_big_script*  script=as=BIG_ACCOUNT
# all scripts in this area to be executed under this account
SET  /database-bin/*  script=as=DBACCNT
</div> 

<p> Access to package scripting directories (e.g. WASD_ROOT:[CGI-BIN]) is
controlled by ACLs and possession of the rights identifier WASD_HTTP_NOBODY. 
If a non-server account requires access to these areas it too will need to be
granted this identifier.

<a id="1.2.3.1.2" href="#"></a>
<a id="1.2.3.1.useraccountscripting" href="#"></a>
<a id="useraccountscripting" href="#"></a>
<h5 class="head"><span class="text">User Account Scripting</span></h5>

<p> In some situations it may be desirable to allow the average Web user to
experiment with or implement scripts.  If the <span class="high italic">set script=as=</span>
mapping rule specifies a tilde character then for a user request the mapped
SYSUAF username is substituted.  Note that this requires the script to be
colocated with the user account Web location and that the script is run under
that account.

<p> The following example shows the essentials of setting up a user environment
where access to a subdirectory in the user's home directory, [.WWW] with
script's located in a subdirectory of that, [.WWW.CGI-BIN].

<div class="blockof code">SET   /~*/www/cgi-bin/*  script=AS=~
UXEC  /~*/cgi-bin/*  /*/www/cgi-bin/*
USER  /~*/*  /*/www/*
REDIRECT  /~*  /~*/
PASS  /~*/*  /dka0/users/*/*
</div> 
 To enable user CGIplus scripting include something like

<div class="blockof code">UXEC+  /~*/cgiplus-bin/*  /*/www/cgi-bin/*
</div> 

<p> Where the site administrator has less than full control of the scripting
environment it may be prudent to put some constraints on the quantity of
resource that potentially can be consumed by non-core or errant scripting. 
The following WASD_CONFIG_MAP rule allows the &quot;maximum&quot; CPU time consumed by a
single script to be constrained.

<div class="blockof code">SET   /cgi-bin/cgi_process  script=CPU=00:00:05
</div> 

<p> Note that this is on a per-script basis, contrasted to the sort of limit a
CPULM-type constraint would place on a scripting process.

<p> The following WASD_CONFIG_GLOBAL rule specifies at which priority the
scripting process executes.  This can be used to provide the server and its
infrastructure an advantage over user scripts.

<div class="blockof code">[DclDetachProcessPriority]  1,2
</div>

See <a class="link" href="scripting001.html#1.2.3.3.processpriorities">1.2.3.3 Process Priorities</a> for further detail.

<a id="1.2.3.1.3" href="#"></a>
<a id="1.2.3.1.authenticateduserscripting" href="#"></a>
<a id="authenticateduserscripting" href="#"></a>
<h5 class="head"><span class="text">Authenticated User Scripting</span></h5>

<p> If the <span class="high italic">set script=as=</span> mapping rule specifies a dollar then a
request that has been SYSUAF authenticated has the SYSUAF username substituted. 
Note that the script itself can be located anywhere provided the user account
has read and/or execute access to the area and file.

<div class="blockof code">SET   /cgi-bin/cgi_process  script=AS=&dollar;
</div> 

<p> If the script has not been subject to SYSUAF authorization then this causes
the script activation to fail.  To allow authenticated requests to be executed
under the corresponding VMS account and non-authenticated requests to script as
the usual server/scripting account use the following variant.

<div class="blockof code">SET   /cgi-bin/cgi_process  script=AS=&dollar;?
</div> 

<p> If the server startup included /PERSONA=AUTHORIZED then only requests that
have been subject to HTTP authorization and authentication are allowed to
script under non-server accounts.

<a id="1.2.3.1.4" href="#"></a>
<a id="1.2.3.1.privilegeduserscripting" href="#"></a>
<a id="privilegeduserscripting" href="#"></a>
<h5 class="head"><span class="text">Privileged User Scripting</span></h5>

<p> By default a privileged account cannot be used for scripting.  This is done
to reduce the chance of unintended capabilities when executing scripts.  With
additional configuration it is possible to use such accounts.  Great care
should be exercised when undertaking this.

<p> To allow the server to activate a script using a privileged account the
keyword /PERSONA=RELAXED must be used with the persona startup qualifier.  If
the keywords /PERSONA=RELAXED=AUTHORIZED are used then privileged accounts are
allowed for scripting but only if the request has been subject to HTTP
authorization and authentication.

<a id="1.2.3.2" href="#"></a>
<a id="1.2.3.2.restrictingpersonascripting" href="#"></a>
<a id="restrictingpersonascripting" href="#"></a>
<h4 class="head"><span class="numb">1.2.3.2</span><span class="text">Restricting Persona Scripting</span></h4>

<p> By default, activating the /PERSONA server startup qualifier allows all the
modes described above to be deployed using appropriate mapping rules.  Of
course there may be circumstances where such broad capabilities are
inappropriate or otherwise undesirable.  It is possible to control which user
accounts are able to be used in this fashion with a rights identifier.  Only
those accounts granted the identifier can have scripts activated under them. 
This means <span class="high under">all</span> accounts &hellip; including the server account!

<div class="note">
<a id="1.2.3.2.1" href="#"></a>
<a id="1.2.3.2.recommendation" href="#"></a>
<a id="recommendation" href="#"></a>
<h5 class="head center"><span class="text">Recommendation</span></h5>
<hr class="note_hr">
The simplest solution might appear to be to just grant all required accounts
the WASD_HTTP_NOBODY identifier described above.  While this is certainly
possible it does provide read access to all parts of the server package this
identifier controls, and write access to the WASD_ROOT:[SCRATCH] default file
scratch space (<a class="link" href="scripting001.html#1.10.scriptingscratchspace">1.10 Scripting Scratch Space</a>).  If scripting outside of the
site administrator's control is being deployed it may be better to create a
separate identifier as just described.
<hr class="note_hr">
</div>

<p> This is enabled by specifying the name of a rights identifier as a
parameter to the /PERSONA qualifier.  This may be any identifier but the 
one shown in the following example is probably as good as any.

<div class="blockof code">&dollar; HTTPD /PERSONA=WASD_SCRIPTING
</div> 

<p> This identifier could be created using the following commands

<div class="blockof code">&dollar; SET DEFAULT SYS&dollar;SYSTEM
&dollar; MCR AUTHORIZE
UAF&gt; ADD /IDENTIFIER WASD_SCRIPTING
</div>
 and granted to accounts using

<div class="blockof code">UAF&gt; GRANT /IDENTIFIER WASD_SCRIPTING HTTP&dollar;NOBODY
</div>

<p> Meaningful combinations of startup parameters are possible:

<div class="blockof code">/PERSONA=(RELAXED)
/PERSONA=(RELAXED=AUTHORIZED)
/PERSONA=(AUTHORIZED,RELAXED)
/PERSONA=(<span class="high italic">ident-name</span>,RELAXED)
/PERSONA=(<span class="high italic">ident-name</span>,AUTHORIZED,RELAXED)
/PERSONA=(<span class="high italic">ident-name</span>,RELAXED=AUTHORIZED)
</div>

<a id="1.2.3.3" href="#"></a>
<a id="1.2.3.3.processpriorities" href="#"></a>
<a id="processpriorities" href="#"></a>
<h4 class="head"><span class="numb">1.2.3.3</span><span class="text">Process Priorities</span></h4>

<p> When detached processes are created they can be assigned differing
priorities depending on the origin and purpose.  The objective is to give the
server process a slight advantage when competing with scripts for system
resources.  This allows the server to respond to new requests more quickly
(reducing latency) even if a script may then take some time to complete the
request.

<p> The allocation of base process priorities is determined from the
WASD_CONFIG_GLOBAL [DclDetachProcessPriority] configuration directive, which
takes one or two (comma-separated) integers that determine how many priorities
lower than the server scripting processes are created.  The first integer
determines server processes.  A second, if supplied, determines user scripts. 
User scripts may never be a higher priority that server scripts.  The following
provides example directives.

<div class="blockof code">[DclDetachProcessPriority]  1
[DclDetachProcessPriority]  0,1
[DclDetachProcessPriority]  1,2
</div>

<p> Scripts executed under the server account, or those created using a mapped
username (i.e. &quot;script=as=<span class="high italic">username</span>&quot;), have a process
priority set by the first/only integer.

<p> Scripts activated from user mappings (i.e. &quot;script=as=~&quot; or
&quot;script=as=&dollar;&quot;) have a process priority set by any second integer, or
fall back to the priority of the first/only integer. 

<a id="1.2.4" href="#"></a>
<a id="1.2.4.scriptprocessdefault" href="#"></a>
<a id="scriptprocessdefault" href="#"></a>
<h3 class="head"><span class="numb">1.2.4</span><span class="text">Script Process Default</span></h3>

<p> For standard CGI and CGIplus script the script process' default device and
directory is established using a SET DEFAULT command immediately before
activating the script.  This default is derived from the script file
specification.

<p> An alternative default location may be specified using the mapping rule
shown in the following example.

<div class="blockof code">set /cgi-bin/this-script* script=default=WEB:[THIS-SCRIPT]
</div>

<p> The default may be specified in VMS or Unix file system syntax as
appropriate.  If in Unix syntax (beginning with a forward-slash) no SET
DEFAULT is performed using DCL.  The script itself must access this value using
the SCRIPT_DEFAULT CGI variable and perform a <span class="high italic">chdir()</span>.

<a id="1.2.5" href="#"></a>
<a id="1.2.5.scriptprocessparsetype" href="#"></a>
<a id="scriptprocessparsetype" href="#"></a>
<h3 class="head"><span class="numb">1.2.5</span><span class="text">Script Process Parse Type</span></h3>

<p> On platforms where the Extended File Specification (EFS) is supported
a SET PROCESS /PARSE=EXTENDED or SET PROCESS /PARSE=TRADITIONAL is executed by
the scripting process before script activation depending on whether the script
path is located on an ODS-2 or ODS-5 volume.

<a id="1.2.6" href="#"></a>
<a id="1.2.6.scriptprocessrundown" href="#"></a>
<a id="scriptprocessrundown" href="#"></a>
<h3 class="head"><span class="numb">1.2.6</span><span class="text">Script Process Run-Down</span></h3>

<p> The server can stop a script process at any point, although this is
generally done at a time and in such a way as to eliminate any disruption to
request processing.  Reasons for the server running-down a script process.

<ul class="list">

<li class="item"> Server script process limit reached.  Less-used must be purged to allow
execution of in-demand scripts.

<li class="item"> A script provides output that is not CGI or NPH compliant (i.e. the
script is obviously in error).

<li class="item"> The administrator proactively purges scripts using the Administration
Menu or command-line /DO=DCL=<span class="high italic">PURGE</span>&verbar;<span class="high italic">DELETE</span>.

<li class="item"> A client has cancelled its request against a long-running script and the
[DclBitBucketTimeout] period expires.

<li class="item"> The script itself exits or deletes its own process.

</ul>

<p> In running down a script process the server must both update its own
internal data structures as well as manage the run-down of the script process
environment and script process itself.  These are the steps.

<ol class="list">

<li class="item"> Exit handling.

<ul class="list">

<li class="item"> If the script process is at DCL level no exit handling is possible.

<li class="item"> If the script is executing an image a &dollar;FORCEX is issued against the
process.  This activates declared exit handlers (standard C library atexit(),
VMS system service &dollar;DCLEXH, etc.).  An exit handler should always be declared
for programs that need to cleanup after themselves or otherwise exit elegantly. 

<p> Generally CGIplus processes delete themselves immediately.  With standard
CGI scripts executing an image it may take from zero to a few seconds for the
image run-down to be detected by the server.  A script is allowed approximately
one minute to complete the image run-down.

</ul>

<li class="item"> Input and output to all of the process' streams is cancelled.  For
scripts that may still be still processing this can result in I/O stream
errors.  The server waits for all queued I/O to disappear.

<li class="item"> If the script process has not already deleted itself the server issues a
&dollar;DELPRC against it.

<li class="item"> The server receives the process termination AST and this completes the
process run-down sequence.

</ol>

<a id="1.2.7" href="#"></a>
<a id="1.2.7.clientrecalcitrance" href="#"></a>
<a id="clientrecalcitrance" href="#"></a>
<h3 class="head"><span class="numb">1.2.7</span><span class="text">Client Recalcitrance</span></h3>

<p> If a client disconnects from a running script (by hitting the browser
<span class="high italic">Stop</span> button, or selecting another hyperlink) the loss of network
connectivity is detected by the server at the next output write.

<p> Generally it is necessary for there to be some mechanism for a client to
stop long-running (and presumably resource consuming) scripts.  Network
disconnection is the only viable one.  Experience would indicate however that
most scripts are short running and most disconnections are due to clients
changing their minds about waiting for a page to build or having seen the page
superstructure moving on to something else.

<p> With these considerations in mind there is significiant benefit in not
running-down a script immediately the client disconnection is detected.  A
short wait will result in most scripts completing their output elegantly (the
script itself unaware the output is not being transmitted on to the client),
and in the case of persistent scripts remaining available for the next request,
or for standard CGI the process remaining for use in the next CGI script.

<p> The period allowing the script to complete its processing may be set using
the WASD_CONFIG_GLOBAL configuration directive [DclBitBucketTimeout].  It
should be set to say fifteen seconds, or whatever is appropriate to the local
site.

<div class="blockof code">[DclBitBucketTimeout]  00:00:15
</div>

<p> NB.  &quot;Bit-bucket&quot; is a common term for the <span class="high italic">place</span>
discarded data is <span class="high italic">stored</span>.  <span class="high monosp">:^)</span>

<a id="1.3" href="#"></a>
<a id="1.3.scriptproctor" href="#"></a>
<a id="scriptproctor" href="#"></a>
<h2 class="head"><span class="numb">1.3</span><span class="text">Script Proctor</span></h2>

<p> Script proctoring proactively creates and maintains the specified minimum
number of scripting processes, configured persistent scripts, and scripting
environments (RTEs).  It is primarily intended for those environments that have
significant startup latency but can also be used to maintain idle scripting
processes ready for immediate use.

<p> The script proctor initially instantiates configured items during server
startup and before enabling request acceptance and processing.

<p> Then during subsequent request processing, at each scripting process
run-down it scans current DCL task list counting the number of instances of
each configured item.  The proctor facility can differentiate between idle and
active instances of the script/RTE and will optionally maintain a specified
number of idle processes in addition to any currently active.  If fewer than
the configured requirement(s) one or more new processes are instantiated.

<p> It is possible (and probably likely) that a proctored script specification
will at some stage fail to activate the script (activation specification error,
script unavailable for some reason, etc.) which would lead to a runaway series
of attempts to proctor with each process exit.  To help avoid this situation
proctored processes that exit before successfully completing initial startup
are quickly suppressed from further proctoring action.  This suppression then
more slowly times out, again allowing proctoring for that item.

<p> <span class="high bold">Proctored scripts and RTEs contain nothing of the usual request-related
environment</span>.  No CGI variables to speak of, no service, no request method,
nothing!  This means that rules used for proctor activations must be outside
all virtual service conditionals (i.e. outside of any specific
[[<span class="high italic">service</span>:<span class="high italic">port</span>]] in the rules, can be inside [[*:*]]) and anything else
that may be dependent on a request characteristic.

<p> The easiest way for a script to detect if its been proctored into existence
is to look for the absence of this or these.  No REQUEST_METHOD is a fair
indicator as it should exist with all &quot;real&quot; requests.   Of course a proctored
script is really just there to instantiate itself, not to do anything directly
productive, and so a script/RTE can just recognise this and conclude with
perhaps a 204 HTTP status (no content) and then remain quiescent (awaiting its
first actual request). Any and all output from a proctored script goes to the
bit-bucket.

<p> Once proctored into existance the script process is then subject to the
normal scripting process management and (for example) if idle for a period
exceeding a lifetime value will be procactively removed.  Of course, during
that process rundown the proctor facility will effectively replace it with a
new instance, maintaining the overall requirement.

<p> The Server Admin, DCL Report includes a Proctor List with the currently
configured proctor items and associated statistics.

<p> Proctored script activation can be WATCHed just like any other script
activation using the [x]CGI and [x]DCL items.  To explicitly trigger such an
event merely &dollar;STOP/ID=<span class="high italic">pid</span> a proctored scripting process.

<a id="1.3.0.0.1" href="#"></a>
<a id="1.3.proctorconfiguration" href="#"></a>
<a id="proctorconfiguration" href="#"></a>
<h5 class="head"><span class="text">Proctor Configuration</span></h5>

<p> Proctor global configuration is introduced with the WASD_CONFIG_GLOBAL
[DclScriptProctor]  item with each following line representing one script/RTE
to be proctored.  Each line contains three mandatory and one optional,
space-separated components.

<ul class="list simple">
<li class="item"> <span class="high italic">integer</span>[+<span class="high italic">integer</span>] <span class="high italic">identification</span> <span class="high italic">activation</span> <span class="high italic">notepad</span>
</ul>

which are, in order

<ol class="list list0">
<li class="item"> the minimum <span class="high italic">integer</span> number of instances of the item 
<br>plus an optional minimum <span class="high italic">integer</span> number of <span class="high under">idle</span> instances
<li class="item"> an <span class="high italic">identification string</span> used to match already running instances of the item
<li class="item"> the <span class="high italic">activation path</span> that can be used to activate the item
<li class="item"> an optional <span class="high italic">string</span> that is passed to the mapping notepad facility
</ol>

<p> The <span class="high italic">zombie</span> form is

<ul class="list simple">
<li class="item"> <span class="high italic">integer</span> * [<span class="high italic">activation</span>]
</ul>

where the specified number of idle <span class="high italic">processes</span> is maintained. 

<p> The minimum plus any idle requirement cannot exceed the [DclSoftLimit]
configuration value (in order to minimise potential process thrashing).

<p> The proctor facility works by matching the identification string to the
script paths as present in the DCL task list (and as presented in the Server
Admin, DCL Report).  So it needs to contain something unique to that script or
environment and often contains a wildcard specification.

<p> The activation path used to activate the script/RTE is the same as if it
was activated via a scripting request.

<p> For an RTE the activation script specification does not actually need to
exist.  It must contain a minimum path to activate the desired environment but
the script itself is not checked to exist by WASD and does not need to exist. 
If it does then it should do whatever is required to instantiate its required
environment and return a 204 (no content) response.  If it does not exist then
the RTE itself should detect it's a proctored activation and return a default
204 response itself, instantiating only the RTE environment.

<div class="note center">
<a id="1.3.0.0.2" href="#"></a>
<a id="1.3.remember" href="#"></a>
<a id="remember" href="#"></a>
<h5 class="head center"><span class="text">Remember</span></h5>
<hr class="note_hr">
Rules for mapping proctored scripts and RTEs must be outside of any
request-dependent conditionals including specific virtual services. 
<hr class="note_hr">
</div>

<p> Proctored scripts can be detected during mapping using

<div class="blockof code">if (proctor:)
</div>

or

<div class="blockof code">if (!request-method:)
</div>
(i.e. no request method) and specific data passed using the optional notepad
string  
(see <a class="link blank" target="_blank" href="../config/#notepadkeyword">Notepad: Keyword</a> of <a class="link blank" target="_blank" href="../config/#0.">WASD Configuration</a>)

and then conditionally processed using something like

<div class="blockof code">if (notepad:<span class="high italic">blah</span>)  
</div>

<p> Specific information can also be passed to the proctored script during
mapping using such conditional processing in concert with the SET

<div class="blockof code">script=param=<span class="high italic">name</span>=<span class="high italic">value</span>
</div>
mapping rule.  This appears as a [WWW_]NAME CGI variable containing the value
specified.  Proctored scripts could then act according to any such data.

<p> The combination of these allows some control of proctored scripting.

<p> A proctor item with a minimum (and optionally idle) value of zero can be
specified as a place-marker; the facility ignores zero valued items.

<a id="1.3.0.0.3" href="#"></a>
<a id="1.3.proctorexample" href="#"></a>
<a id="proctorexample" href="#"></a>
<h5 class="head"><span class="text">Proctor Example</span></h5>

<p> This example illustrates a number of non-trivial proctoring scenarios. 
Only configuration items directly involved in the proctoring are shown; others
would be involved in the general web-server infrastructure.

<div class="blockof code"># WASD_CONFIG_GLOBAL
[DclScriptProctor]
2 /cgiplus-bin/mgd* /cgiplus-bin/mgd proctor=daniel
2 /apps/script /apps/script anyoldname=dothis
3+1 (*pyrte*)* /py-bin/proctor.py
2 *
3 * proctor=daniel
</div>

<p> The [DclScriptProctor] contains five items.  The first two specify that
two scripts each be maintained, the third specifies four, the final two
maintain zombie <span class="high italic">processes</span>.  The mapping  rules (below) contain a
conditional detecting the absence of a REQUEST_METHOD and processing the
proctored scripts inside that decision structure.  Proctor-specific mapping
rules tend to be used only to supplement otherwise fundamental (but in this
case proctored) scripting.

<div class="blockof code"># WASD_CONFIG_MAP
if (proctor:)
   if (notepad:proctor=daniel) set * script=as=daniel
   if (notepad:anyoldname=dothis) set * script=param=DOTHIS=one
   # not a real script of course!
   script proctor=daniel proctor=daniel script=as=daniel
endif
</div>
 Each of the five items explained in order:

<ol class="list">

<li class="item"> Matches the CGIplus script &quot;/cgiplus-bin/mgd&quot; and the trailing wildcard
any supplementary path provided to that script.  The activation path is a
straight-forward scripting path.  An optional notepad datum is passed to the
mapping facility.  In the mapping rules the notepad datum supplied is detected
(&quot;if (notepad:proctor=daniel)&quot;) and the username under which the script is to
be executed specified.  A minimum of two instances of this script are
maintained.                    

<li class="item"> Matches the script &quot;/apps/script&quot; without trailing wildcard (as it is
&ndash; a hypothetical &ndash; never used with a supplementary path).  The activation
path is again the straight-forward scripting path.  An optional notepad datum
is also passed from the proctor configuration to mapping which specifically
detects it and set as CGI variable name and value that can subsequently be
detected and acted upon by the proctored script.  A minimum of two instances of
this script are maintained.

<li class="item"> Maintains a scripting environment (RTE) and is therefore a little less
straight-forward.  The intention is to maintain a minimum number of Python RTEs
(a rather expensive-to-instantiate interpreter).  The matching string is more
focused on the underlying RTE.  The RTE is not obvious in the activation path
(as all RTE mapping is transparent to the script path).  The RTE is the
environment of interest though and so is the matching string of interest;
&quot;(*pyrte*)*&quot;, where the parentheses indicate an underlying RTE, the wildcards
delimit the RTE name of interest, and the trailing wildcard matches any current
script that the RTE may be executing.  The Server Admin menu, DCL Report can be
used to gain insight into any script or scripting environment strings to be
matched.  In this third case there is no supplementary mapping required.  A
minimum of three instances of this RTE are maintained at least one of which
must be idle or an additional instance will be created.

<li class="item"> Maintains two idle scripting <span class="high italic">processes</span> (under the default scripting
account) available for scripting use without the latency of process creation. 

<li class="item"> Maintains three idle scripting <span class="high italic">processes</span> with an associated mapping
rule to activate them using the specified username.  The <span class="high italic">activation</span> string
is arbitrary, should be unique, and is the  &quot;path&quot; when being mapped.  A
<span class="high italic">notepad</span> string can be specified.

</ol>

<a id="1.4" href="#"></a>
<a id="1.4.cachingscriptoutput" href="#"></a>
<a id="cachingscriptoutput" href="#"></a>
<h2 class="head"><span class="numb">1.4</span><span class="text">Caching Script Output</span></h2>

<p> The WASD cache was originally provided to reduce file-system access (a
somewhat expensive activity under VMS).  With the expansion in the use of
dynamically generated page content (e.g. PHP, Perl, Python) there is an obvious
need to reduce the system impact of some of these activities.  While many such
responses have content specific to the individual request a large number are
also generated as general site pages, perhaps with simple time or date
components, or other periodic information.  Non-file caching is intended for
this type of dynamic content.

<p> Revalidation of non-file content is difficult to implement for a number of
reasons, both by the server and by the scripts, and so is not provided. 
Instead the cache entry is flushed on expiry of the  [CacheValidateSeconds], or
as otherwise specified by path mapping, and the request is serviced by the
content source (script, PHP, Perl, etc.) with the generated response being
freshly cached.  Browser requests specifying no-caching are honoured (within
server configuration parameters) and will flush the entry, resulting in the
content being reloaded.

<a id="1.4.0.0.1" href="#"></a>
<a id="1.4.controllingscriptcaching" href="#"></a>
<a id="controllingscriptcaching" href="#"></a>
<h5 class="head"><span class="text">Controlling Script Caching</span></h5>

<p> Determining which script content is to be cached and which not, and how long
before flushing, is done using mapping rules (described in detail in
<a class="link blank" target="_blank" href="../config/#requestprocessingconfiguration">Request Processing Configuration</a> of <a class="link blank" target="_blank" href="../config/#0.">WASD Configuration</a>).  
The source  of script cache content is specified  using one or a combination of
the following SET rules against general or specific paths in WASD_CONFIG_MAP. 
All mapping rules (script and non-script) are described here to put the script
oriented ones into context.  Those specific to script output caching are noted.

<ul class="list simple list0">
<li class="item"> <span class="high bold">cache=[no]cgi </span> from Common Gateway Interface (CGI) responses (<span class="high bold">for script output</span>)
<li class="item"> <span class="high bold">cache=[no]file </span> from the file system (default and pre-8.4 cache behaviour)
<li class="item"> <span class="high bold">cache=[no]net </span> caches the full data stream irrespective of the source
<li class="item"> <span class="high bold">cache=[no]nph </span> full stream from Non-Parse Header (NPH) response (<span class="high bold">for script output</span>)
<li class="item"> <span class="high bold">cache=[no]query </span> cache requests with query strings (<span class="high bold">use with care</span>)
<li class="item"> <span class="high bold">cache=[no]script </span> both CGI and NPH responses (<span class="high bold">for script output</span>)
<li class="item"> <span class="high bold">cache=[no]ssi </span> from Server-Side Includes (SSI) documents
</ul>

<p> A good understanding of site requirements and dynamic content sources, 
along with considerable care in specifying cache path SETings, is required to
cache dynamic content effectively.  It is especially important to get the
content revalidation period appropriate to the content of the pages.  This is
specified using the following path SETings.

<ul class="list simple list0">
<li class="item"> <span class="high bold">cache=expires=0 </span> cancels any expiry
<li class="item"> <span class="high bold">cache=expires=DAY </span> expires when the day changes
<li class="item"> <span class="high bold">cache=expires=HOUR </span> when the hour changes
<li class="item"> <span class="high bold">cache=expires=MINUTE </span> when the minute changes
<li class="item"> <span class="high bold">cache=expires=&lt;hh:mm:ss&gt; </span> expires after the specified period in the cache
</ul>

<a id="1.4.0.0.2" href="#"></a>
<a id="1.4.examples" href="#"></a>
<a id="examples" href="#"></a>
<h5 class="head"><span class="text">Examples</span></h5>

<p> To cache the content of PHP-generated home pages that
contain a  time-of-day clock, resolving down to the minute, would require a
mapping rule similar to the following.

<div class="blockof code">set /**/index.php cache=cgi cache=expires=minute
</div>

<p> To prevent requests from flushing a particular scripts output (say the main
page of a site) using no-cache fields until the server determines that it needs
reloading use the cache <span class="high italic">guard</span> period.

<div class="blockof code">set /index.py cache=script cache=expires=hour cache=guard=01:00:00
</div>

<a id="1.5" href="#"></a>
<a id="1.5.enablingascript" href="#"></a>
<a id="enablingascript" href="#"></a>
<h2 class="head"><span class="numb">1.5</span><span class="text">Enabling A Script</span></h2>

<p> By default the server accesses scripts using the search list logical name
CGI-BIN, although this can be significantly changed using mapping rules. 
CGI-BIN is defined to first search WASD_ROOT:[CGI-BIN] and then
WASD_ROOT:[AXP-BIN], WASD_ROOT:[IA64-BIN], or WASD_ROOT:[X86_64-BIN] depending
on the platform.  [CGI-BIN] is intended for architecture-neutral script files
(.CLASS., COM, .PL, .PY, etc.) and the architecture specific directories for
executables (.EXE, .DLL, etc.)

<p> These directories are delivered empty and it is up to the site to populate
them with the desired scripts. A script is made available by copying its
file(s) into the appropriate directory.  By default ACLs will be propagated to
allow access by the default scripting account.  Scripts can be made unavailable
by deleting them from these directories.

<div class="note">
<a id="1.5.0.0.1" href="#"></a>
<a id="1.5.minimiseavailablescripts" href="#"></a>
<a id="minimiseavailablescripts" href="#"></a>
<h5 class="head center"><span class="text">Minimise available scripts</span></h5>
<hr class="note_hr">
It is good security practice to deploy only those scripts a site is actually
using.  This minimises vulnerability by simply reducing the number of possibly
problematic scripts.  A periodic audit of script directories is a good policy.
<hr class="note_hr">
</div>

<p> WASD script executables are built into the WASD_ROOT:[AXP], WASD_ROOT:[IA64]
or WASD_ROOT:[X86_64] directories depending on the architecture.  Other script
files, such as DCL procedures, Perl examples, Java class examples, etc. are
located in other directories in the WASD_ROOT:[SRC] tree.  The procedure
<a class="link blank" target="_blank" href="/wasd_root/install/scripts.com">WASD_ROOT:[INSTALL]SCRIPTS.COM</a> assists
in the installation or deinstallation of groups of WASD scripts.

<a id="1.6" href="#"></a>
<a id="1.6.scriptmapping" href="#"></a>
<a id="scriptmapping" href="#"></a>
<h2 class="head"><span class="numb">1.6</span><span class="text">Script Mapping</span></h2>

<p> Scripts are enabled using the <span class="high italic">exec</span>/<span class="high italic">uxec</span> or <span class="high italic">script</span> rules in the
mapping file (also see
<a class="link blank" target="_blank" href="../config/#requestprocessingconfiguration">Request Processing Configuration</a> of <a class="link blank" target="_blank" href="../config/#0.">WASD Configuration</a>).
The script portion of the <span class="high italic">result</span> must be a URL equivalent of the physical
VMS procedure or executable specification.

<p> All files in a directory may be mapped as scripts using the
<span class="high italic">exec</span> rule.  For instance, in the WASD_CONFIG_MAP configuration file can
be found a rule

<div class="blockof code">exec /cgi-bin/* /cgi-bin/*
</div>

which results in request paths beginning &quot;/cgi-bin/&quot; having the following path
component mapped as a script.  Hence a path &quot;/cgi-bin/cgi_symbols.com&quot; will
result in the server attempting to execute a file named
CGI-BIN:[000000]CGI_SYMBOLS.COM.

<p> Multiple such paths may be designated as <span class="high italic">exec</span>utable, with their
contents expected to be scripts, either directly executable by VMS (e.g. .EXEs
and .COMs) or processable by a designated interpreter, etc., (e.g. .PLs,
.CLASSes) (<a class="link" href="scripting004.html#4.runtimeenvironments">4. Run-Time Environments</a>).

<p> In addition individual files may be specified as scripts.  This is done
using the <span class="high italic">script</span> rule.  In the following example the request path
&quot;/help&quot; activates the &quot;Conan The Librarian&quot; script.

<div class="blockof code">script /help* /cgi-bin/conan*
</div>

<p> Of course, multiple such rules may be used to map such abbreviated or
self-explanatory script paths to the actual script providing the application.

<a id="1.6.0.0.1" href="#"></a>
<a id="1.6.mappinglocalorthirdpartyscripts" href="#"></a>
<a id="mappinglocalorthirdpartyscripts" href="#"></a>
<h5 class="head"><span class="text">Mapping Local or Third-Party Scripts</span></h5>

<p> It is not necessary to move/copy scripts into the server directory
structure to make them accessible.  In fact there are probably good reasons
for not doing so!  For instance, it keeps a package together so that at the
next upgrade there is no possibility of the &quot;server-instance&quot; of that
application being overlooked.

<p> To make scripts provided by third party packages available for server
activation three requirements must be met.

<ol class="list">

<li class="item"> The <span class="high bold">server</span> account (HTTP&dollar;SERVER by default) must have
read and execute access to the directory containing the scripts.  Script files
are searched for by the server before activation is attempted.  This can be
enabled using the SECHAN utility
(see <a class="link blank" target="_blank" href="../features/#sechanutility">Sechan Utility</a> in <a class="link blank" target="_blank" href="../features/#0.">WASD Features</a>).

<div class="blockof code">&dollar; SECHAN /ASIF=CGI-BIN device:[directory]script-directory.DIR
</div>

<li class="item"> The <span class="high bold">scripting</span> account (HTTP&dollar;NOBODY by default) must have
read and execute access  to any and all images and other resources required to
use the application.  There may be some consideration of file protections
required when multiple accessors need to be accomodated (e.g. scripting and
application accounts) so a specific solution may be required.  If only the
scripting account requires read access then the SECHAN utility could again be
used to provide that to the directory (or directories) and contained files.

<div class="blockof code">&dollar; SECHAN /ASIF=CGI-BIN device:[000000]directory.DIR
&dollar; SECHAN /ASIF=CGI-BIN device:[directory]*.*
</div>

<li class="item"> Mapping rules must exist to make the script and any required resources
accessible.

</ol>

<p> Most packages having such an interface for Web server access would
provide details on mapping into the package directory.  For illustration the
following mapping rules provide access to a package's scripts (assuming it
provides more than one) and also into a documentation area.

<p> The hypothetical &quot;Application X&quot; directory locations are

<div class="blockof code">APPLICATIONX_ROOT:[DOC]
APPLICATIONX_ROOT:[CGI-BIN]
</div>

<p> The required mapping rules would be

<div class="blockof code">pass /applicationX/* /applicationX_root/docs/*
exec /appX-bin/* /applicationX_root/cgi-bin/*
</div>

<p> Access to X's scripts would be using a path such as

<div class="blockof code">http://the.host.name/appx-bin/main_script?plus=some&amp;query=string
</div>

<div class="note">
<a id="1.6.0.0.2" href="#"></a>
<a id="1.6.carefulofthirdpartyscriptlocations" href="#"></a>
<a id="carefulofthirdpartyscriptlocations" href="#"></a>
<h5 class="head center"><span class="text">Careful of third-party script locations</span></h5>
<hr class="note_hr">
When allowing the server and scripting account access into parts of the file
system outside of the WASD package it is recommended to control the environment
very carefully.  Third-party scripting areas in particular should be modelled
on those present in the package itself
(see <a class="link blank" target="_blank" href="../features/#sechanutility">Sechan Utility</a> in <a class="link blank" target="_blank" href="../features/#0.">WASD Features</a>)
<hr class="note_hr">
</div>

<a id="1.6.0.0.3" href="#"></a>
<a id="1.6.quotwrappingquotlocalorthirdpartyscripts" href="#"></a>
<a id="quotwrappingquotlocalorthirdpartyscripts" href="#"></a>
<h5 class="head"><span class="text">&quot;Wrapping&quot; Local or Third-Party Scripts</span></h5>

<p> Sometimes it may be necessary to provide a particular non-WASD, local, or
third-party script with a particular environment in which to execute.  This can
be provided by <span class="high italic">wrapping</span> the script executable or interpreted script
in a DCL procedure (of course, if the local or third-party script is already
activated by a DCL procedure, then that may need to be directly modified). 
Simply create a DCL procedure, in the same directory as the script executable,
containing the required environmental commands.

<p> For example, the following DCL procedure defines a scratch directory and
provides the location of the configuration file.  It is assumed the script
executable is APPLICATIONX_ROOT:[CGI-BIN]APPX.EXE and the script wrapper
APPLICATIONX_ROOT:[CGI-BIN]APPX.COM.

<div class="blockof code">&dollar;! wrapper for APPX CGI executable
&dollar; SET DEFAULT APPLICATIONX_ROOT:[000000]
&dollar; DEFINE /USER SYS&dollar;SCRATCH APPLICATIONX_ROOT:[SCRATCH]
&dollar; APPX == &quot;&dollar;APPLICATIONX_ROOT:[CGI-BIN]APPX&quot;
&dollar; APPX /CONFIG=APPLICATIONX_ROOT:[CONFIG]APPX.CONF
</div>

<a id="1.7" href="#"></a>
<a id="1.7.scriptruntime" href="#"></a>
<a id="scriptruntime" href="#"></a>
<h2 class="head"><span class="numb">1.7</span><span class="text">Script Run-Time</span></h2>

<p> A script is merely an executed or interpreted file. Although by default VMS
executables and DCL procedures can be used as scripts, other environments may
also be configured. For example, scripts written for the Perl language may be
transparently given to the Perl interpreter in a script process. This type of
script activation is based on a unique file type (extension following the file
name), for the Perl example this is most commonly &quot;.PL&quot;, or sometimes &quot;.CGI&quot;.
Both of these may be configured to automatically invoke the site's Perl
interpreter, or any other for that matter. 

<p> This configuration is performed using the WASD_CONFIG_GLOBAL
[DclScriptRunTime]  directive, where a file type is associated with a run-time
interpreter. This parameter takes two components, the file extension and the
run-time verb. The verb may be  specified as a simple, globally-accessible verb
(e.g. one embedded in the CLI tables), or in the format to construct a
<span class="high italic">foreign-verb</span>, providing reasonable versatility. Run-time parameters may
also be appended to the verb if desired. The server ensures the verb is
foreign-assigned if necessary, then used on a command line with the script file
name as the final parameter to it.

<p> The following is an example showing a Perl interpreter being specified.  The
first line assumes the &quot;Perl&quot; verb is globally accessible on the system (e.g.
perhaps provided by the DCL&dollar;PATH logical) while the second (for the sake of
illustration) shows the same Perl interpreter being configured for a different
file type using the foreign verb syntax.

<div class="blockof code">[DclScriptRunTime]
.PL PERL
.CGI &dollar;PERL_EXE:PERL
</div>

<p> A file contain a Perl script then may be activated merely by specifying a
path such as the following

<div class="blockof code">/cgi-bin/example.pl
</div>

<p> To add any required parameters just append them to the verb specified.

<div class="blockof code">[DclScriptRunTime]
.XYZ XYZ_INTERPRETER -vms -verbose -etc
.XYZ &dollar;XYZ_EXE:XYZ_INTERPRETER /vms /verbose /etc
</div>

<p> If a more complex run-time interpreter is required it may be necessary to
<span class="high italic">wrap</span> the script's execution in a DCL procedure.

<a id="1.7.0.0.1" href="#"></a>
<a id="1.7.scriptfileextensions" href="#"></a>
<a id="scriptfileextensions" href="#"></a>
<h5 class="head"><span class="text">Script File Extensions</span></h5>

<p> The WASD server does not require a file type (extension) to be explicitly
provided when activating a script. This can help hide the implementation detail
of any script. If the script path does not contain a file type the server
searches the script location for a file with one of the known file types, first
&quot;.COM&quot; for a DCL procedure, then &quot;.EXE&quot; for an executable, then any file types
specified using script run-time configuration directive, in the order
specified.

<p> For instance, the script activated in the Perl example above could have been
specified as below and (provided there was no &quot;EXAMPLE.COM&quot; or &quot;EXAMPLE.EXE&quot; in
the search) the same script would have been executed.

<div class="blockof code">/cgi-bin/example
</div>

<a id="1.8" href="#"></a>
<a id="1.8.unixsyntax" href="#"></a>
<a id="unixsyntax" href="#"></a>
<h2 class="head"><span class="numb">1.8</span><span class="text">Unix Syntax</span></h2>

<p> CGI environment variables SCRIPT_FILENAME and PATH_TRANSLATED can be
provided to any script (CGI, CGIplus, RTE) in Unix file-system syntax should
that script require or prefer it using this format.

<p> The path mapping rule &quot;SET script=syntax=unix&quot; changes the default syntax
from VMS to Unix file-system.  For example; by default using the URL

<div class="blockof code">/cgi-bin/cgi_symbols/wasd_root/src/
</div>

would provide the request CGI data

<div class="blockof code">WWW_PATH_INFO == &quot;/wasd_root/src/&quot;
WWW_PATH_TRANSLATED == &quot;WASD_ROOT:[SRC]&quot;
WWW_REQUEST_URI == &quot;/cgi-bin/cgi_symbols/wasd_root/src/&quot;
WWW_SCRIPT_FILENAME == &quot;CGI-BIN:[000000]CGI_SYMBOLS.COM&quot;
WWW_SCRIPT_NAME == &quot;/cgi-bin/cgi_symbols&quot;
</div>

<p> If the script path had been specifically mapped using

<div class="blockof code">set /cgi-bin/cgi_symbols* script=syntax=unix
</div>

the same CGI data would be provided as

<div class="blockof code">WWW_PATH_INFO == &quot;/wasd_root/src/&quot;
WWW_PATH_TRANSLATED == &quot;/wasd_root/SRC/&quot;
WWW_REQUEST_URI == &quot;/cgi-bin/cgi_symbols/wasd_root/src/&quot;
WWW_SCRIPT_FILENAME == &quot;/CGI-BIN/000000/CGI_SYMBOLS.COM&quot;
WWW_SCRIPT_NAME == &quot;/cgi-bin/cgi_symbols&quot;
</div>

<p> Note that the CGI or CGIplus script file is still activated using VMS
file-system syntax, it is just the CGI representation that is changed.  This
can be particularly useful for environments ported from Unix expecting to
manipulate paths using Unix syntax.  This would most commonly occur with RTE
engines such as PHP, Perl, etc.

<a id="1.9" href="#"></a>
<a id="1.9.scriptinglogicals" href="#"></a>
<a id="scriptinglogicals" href="#"></a>
<h2 class="head"><span class="numb">1.9</span><span class="text">Scripting Logicals</span></h2>

<p> Two logicals provide some control of and input to the DCL process
scripting environment (which includes standard CGI, CGIplus and ISAPI,
DECnet-based CGI, but excludes DECnet-based OSU).

<ul class="list">

<li class="item"> <span class="high bold">HTTPD&dollar;LOGIN &ndash; </span> Specifies the location of a command procedure that
can be executed <span class="high under">immediately</span> before the script procedure/image/script-file is
activated.  This is intended for the provision of a common per-site
environment, etc., but could be used for any purpose. Activate using a
system-wide logical as in the following example.

<div class="blockof code">&dollar; DEFINE /SYSTEM HTTPD&dollar;LOGIN WASD_ROOT:[HTTP&dollar;NOBODY]HTTPD&dollar;LOGIN.COM
</div>

<p> Note that each layer of execution added to the scripting environment
increases both system overhead and response latency.

<li class="item"> <span class="high bold">HTTPD&dollar;VERIFY &ndash; </span> Activates DCL verify for the DCL process scripting
environment.  This shows the DCL commands used to support script activation. 
Intended for problem investigation.

<div class="blockof code">&dollar; DEFINE /SYSTEM HTTPD&dollar;VERIFY 1
</div>

<p> If the logical name value is a dotted-decimal specified IP address the
verify is only applied to scripts associated with requests originating from
that address.  This is useful when trying to trouble-shoot scripts on a live
server.

<div class="blockof code">&dollar; DEFINE /SYSTEM HTTPD&dollar;VERIFY 192.168.0.2
</div>

</ul>

<p> Note that most WASD scripts also contain logical names that can be set for
debugging purposes.  These are generally in the format <span class="high italic">script_name</span>&dollar;DBUG and
if exist activate debugging statements throughout the script.

<a id="1.10" href="#"></a>
<a id="1.10.scriptingscratchspace" href="#"></a>
<a id="scriptingscratchspace" href="#"></a>
<h2 class="head"><span class="numb">1.10</span><span class="text">Scripting Scratch Space</span></h2>

<p> Scripts often require temporary file space during execution.  Of course
this can be located anywhere the scripting account (most often HTTP&dollar;SERVER) has
appropriate access.  The WASD package does provide a default area for such
purposes with permissions set during startup to allow the server account full
access.  The default area is located in

<div class="blockof code">WASD_ROOT:[SCRATCH]
</div>

as is accessed by the server and scripts using the logical name

<div class="blockof code">WASD_SCRATCH:
</div>

<p> The server provides for the routine clean-up of old files in WASD_SCRATCH:
left behind by aborted or misbehaving scripts (although as a matter of design
all scripts should attempt to clean up after themselves).  The
WASD_CONFIG_GLOBAL directives

<div class="blockof code">[DclCleanupScratchMinutesMax]
[DclCleanupScratchMinutesOld]
</div>

control how frequently the clean-up scan occurs, and how old files need to be
before being deleted.  Whenever script processes are active the scratch area is
scanned at the maximum period specified, or whenever the last script process is
purged from the system by the server.

<p> Of course there is always the potential for interaction between scripts
using a common area for such purposes.  At the most elemetary, care must be
taken to ensure unique file name are generated.  At worst there is the
potential for malicious interaction and information leakage.  Use such common
areas with discretion.

<div class="note center">
<a id="1.10.0.0.1" href="#"></a>
<a id="1.10.sharedscratchareas" href="#"></a>
<a id="sharedscratchareas" href="#"></a>
<h5 class="head center"><span class="text">Shared scratch areas</span></h5>
<hr class="note_hr">
<span class="high bold">Beware!</span>  They rely on cooperation between scripts for minimising potential
interactions.
<br> They alo can be a source of unintended or malicious information leakage.
<hr class="note_hr">
</div>

<a id="1.10.0.0.2" href="#"></a>
<a id="1.10.uniquefilenamesndashdcl" href="#"></a>
<a id="uniquefilenamesndashdcl" href="#"></a>
<h5 class="head"><span class="text">Unique File Names &ndash; DCL</span></h5>

<p> The &quot;UNIQUE_ID&quot; CGI variable provides a <span class="high under">unique</span> 19 character alpha-numeric
string (<a class="link" href="scripting002.html#2.1.uniqueidnote">&lsquo;UNIQUE_ID Note&rsquo; in 2.1 CGI Environment Variables</a>) suitable for many uses including the type
extension of temporary files.  The following DCL illustrates the essentials of
generating a script-unqiue file name.  For mutliple file names add further text
to the type, as shown below.

<div class="blockof code">&dollar; SCRATCH_DIR = &quot;WASD_SCRATCH:&quot;
&dollar; PROC_NAME = F&dollar;PARSE(F&dollar;ENVIRONMENT(&quot;PROCEDURE&quot;),,,&quot;NAME&quot;)
&dollar; INFILE_NAME = SCRATCH_DIR + PROC_NAME + &quot;.&quot; + WWW_UNIQUE_ID + &quot;_IN&quot;
&dollar; OUTFILE_NAME = SCRATCH_DIR + PROC_NAME + &quot;.&quot; + WWW_UNIQUE_ID + &quot;_OUT&quot;
</div>

<a id="1.10.0.0.3" href="#"></a>
<a id="1.10.uniquefilenamesndashclanguage" href="#"></a>
<a id="uniquefilenamesndashclanguage" href="#"></a>
<h5 class="head"><span class="text">Unique File Names &ndash; C Language</span></h5>

<p> A similar approach can be used for script coded using the C language, with
the useful capacity to mark the file for delete-on-close (of course this is
only really useful if it is, say, only to be written, rewound and then re-read
without closing first &ndash; but I'm sure you get the idea).

<div class="blockof code">#define WASD_SCRATCH &quot;WASD_SCRATCH:&quot;
#define SCRIPT_NAME &quot;EXAMPLE&quot;

char  *unqiueId;
char  tmpFileName [256];
FILE  *tmpFile;

if ((uniqueId = getenv(&quot;WWW_UNIQUE_ID&quot;)) == NULL)
{
   printf (&quot;Error: WWW_UNIQUE_ID absent!\n&quot;);
   exit (1);
}
sprintf (tmpFileName, WASD_SCRATCH SCRIPT_NAME &quot;.%s&quot;, uniqueId);

if ((tmpFile = fopen (tmpFileName, &quot;w+&quot;, &quot;fop=dlt&quot;)) == NULL)
   exit (vaxc&dollar;errno); 
</div>

<a id="1.11" href="#"></a>
<a id="1.11.dclprocessingofrequests" href="#"></a>
<a id="dclprocessingofrequests" href="#"></a>
<h2 class="head"><span class="numb">1.11</span><span class="text">DCL Processing of Requests</span></h2>

<p> DCL is the native scripting environment for VMS and provides a rich set of
constructs and capabilities for <span class="high italic">ad hoc</span> and low usage scripting, and as a
<span class="high italic">glue</span> when several processing steps need to be undertaken for a particular
script.  In common with many interpreted environments care must be taken with
effective exception handling and data validation.  To assist with the
processing of request content and response generation from within DCL
procedures the CGIUTL utility is available in
<a class="link blank" target="_blank" href="/wasd_root/src/misc/*cgiutl*.*">WASD_ROOT:[SRC.MISC]</a>

<p> Functionality includes

<ul class="list list0">
<li class="item"> decode a POSTed request body into DCL symbols
<li class="item"> write a POSTed request body to a file
<li class="item"> <span class="high italic">massage</span> DCL symbol quotation characters
<li class="item"> generate HTTP response headers
<li class="item"> <span class="high italic">binary</span> transfer of file contents
</ul>

<p> Most usefully it can read the request body, decoding form-URL-encoded
contents into DCL symbols and/or a scratch file, allowing a DCL procedure to
easily and effectively process this form of request.

<div class="note">
<a id="1.11.0.0.1" href="#"></a>
<a id="1.11.neversubstitute" href="#"></a>
<a id="neversubstitute" href="#"></a>
<h5 class="head center"><span class="text">NEVER substitute...</span></h5>
<hr class="note_hr">
...the content of CGI variables directly into the code stream using
interpreters that will allows this (e.g. DCL, Perl).  You run a very real risk
of having unintended content maliciously change the intended function of the
code.  For example, never use comma substitution of a CGI variable at the DCL
command line as in
<div class="blockof code">&dollar; COPY 'WWW_FORM_SRC' 'WWW_FORM_DST'
</div>
Always pre-process the content of the variable first, ensuring there has
been nothing inserted that could subvert the intended purpose.  The CGIUTL
assists complying with this rule by providing an explicit, non-DCL substitution
character for use on the command-line (see source code descriptive prologue).
<hr class="note_hr">
</div>

<a id="1.12" href="#"></a>
<a id="1.12.scriptingfunctionlibrary" href="#"></a>
<a id="scriptingfunctionlibrary" href="#"></a>
<h2 class="head"><span class="numb">1.12</span><span class="text">Scripting Function Library</span></h2>

<p> A source code collection of C language functions useful for processing the
more vexing aspects of CGI and general script programming is available in
CGILIB.  This and an example implementation is available in
<a class="link blank" target="_blank" href="/wasd_root/src/misc/*cgilib*.*">WASD_ROOT:[SRC.MISC]</a>

<p> Functionality includes

<ul class="list list0">

<li class="item"> detection and appropriate initialization of the scripting environment,
including WASD, CGIplus, VMS Apache, OSU, Purveyor, and possibly other CGI
(e.g. Cern, Netscape FastTrack)

<li class="item"> transparent access to CGI variables

<li class="item"> transparent access to the body of a POSTed request, both URL-encoded and
MIME multipart/form-data (from &lt;input type=&quot;file&quot;&gt; upload tags)

<li class="item"> placing the contents of a form-URL-encoded or multipart/form-data body
into CGI-like environment variables

<li class="item"> URL-decoding, URL-encoding and HTML-escaping a string

<li class="item"> CGIplus-specific functionality (including callouts)

</ul>

<p> The WASD scripts use this library extensively and may serve as example
applications.

<a id="1.13" href="#"></a>
<a id="1.13.scriptrequestedservergeneratederrorresponses" href="#"></a>
<a id="scriptrequestedservergeneratederrorresponses" href="#"></a>
<h2 class="head"><span class="numb">1.13</span><span class="text">Script-Requested, Server-Generated Error Responses</span></h2>

<p> Of course a script can generate any output it requires including
non-success (non-200) pages (e.g. 400, 401, 302, etc.)  For error pages a
certain consistency results from making these substantially the same layout and
content as those generated by the server itself.  To this end, script response
header output can contain one or more of several extension fields to indicate
to the server that instead of sending the script response to the client it
should internally generate an error response using the script-supplied
information.  These fields are listed in <a class="link" href="scripting002.html#2.2.1.scriptcontrol">&lsquo;Script-Control:&rsquo; in 2.2.1 CGI Compliant Output</a> section of
<a class="link" href="scripting002.html#2.2.1.cgicompliantoutput">2.2.1 CGI Compliant Output</a> and are available in any scripting environment.

<p> If a &quot;Script-Control: X-error-text=&quot;<span class="high italic">text of error message</span>&quot;&quot; field occurs
in the script response header the server stops processing further output and
generates an error message.  Other <span class="high italic">error</span> fields can be used to provide
additional or message-modifying information.  A significant example is the
&quot;Script-Control: X-error-vms-status=<span class="high italic">integer</span>&quot; field which supplies a VMS
status value for a more detailed, status-related error message explanation.

<p> Essentially the script just generates a standard CGI &quot;Status: <span class="high italic">nnn</span>&quot;
response and includes at least the &quot;X-error-text=&quot; field before the
header-terminating empty record (blank line).  Some variations are shown in the
following DCL examples.

<div class="blockof code">&dollar;! vanilla error message
&dollar; say = &quot;write sys&dollar;output&quot;
&dollar; say &quot;Status: 400&quot;
&dollar; say &quot;Script-Control: X-error-text=&quot;&quot;Confusing URL components!&quot;&quot;&quot;
&dollar; say &quot;&quot;

&dollar;! VMS status error message 
&dollar; say = &quot;write sys&dollar;output&quot;
&dollar;! &quot;status: 000&quot; allows the server to select the HTTP status code
&dollar; say &quot;Status: 000&quot;
&dollar; say &quot;Script-Control: X-error-text=&quot;&quot;/a/file/name.txt&quot;&quot;&quot;
&dollar; say &quot;Script-Control: X-error-vms-status=%X00000910&quot;
&dollar; say &quot;Script-Control: X-error-vms-text=&quot;&quot;A:[FILE]NAME.TXT&quot;&quot;&quot;
&dollar; say &quot;&quot;

&dollar;! add META source module name and line generating message
&dollar; say = &quot;write sys&dollar;output&quot;
&dollar; say &quot;Status: 500&quot;
&dollar; say &quot;Script-Control: X-error-text=&quot;&quot;Don't know what to do now...&quot;&quot;&quot;
&dollar; say &quot;Script-Control: X-error-module=EXAMPLE; X-error-line=999&quot;
&dollar; say &quot;&quot;
</div>

<p> Interestingly, because CGI environments should ignore response fields
unknown to them, for scripts deployed across multiple server platforms it
should be possible to have these WASD-specific elements in every header for
WASD uses followed by other explicitly error page content for use in those
other environments.

<div class="blockof code">&dollar;! WASD error content, plus other platform content
&dollar; say = &quot;write sys&dollar;output&quot;
&dollar; say &quot;Status: 404&quot;
&dollar; say &quot;Script-Control: X-error-text=&quot;&quot;Requested object not found.&quot;&quot;&quot;
&dollar; say &quot;Content-Type: text/html&quot;
&dollar; say &quot;&quot;
&dollar; say &quot;&lt;B&gt;ERROR 404:&lt;/B&gt;&amp;nbsp; Requested object not found.&quot;
</div>

<p> An example implemented using DCL is available

<div class="blockof mono"><a class="link blank" target="_blank" href="/wasd_root/src/other/request_error_msg.com">WASD_ROOT:[SRC.OTHER]REQUEST_ERROR_MSG.COM</a>
</div>

and if currently enabled for scripting

<div class="blockof mono"><a class="link blank" target="_blank" href="/cgi-bin/request_error_msg">/cgi-bin/request_error_msg</a>
</div>

<!-- source:0200_CGI.WASDOC -->

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="scripting000.html#0.">&#8598;&#xFE0E;</a>
<td><a href="scripting000.html#0.">&#8593;&#xFE0E;</a>
<td><a href="scripting002.html#2.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>