[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]
/*****************************************************************************/
/*
                                  DAVprop.c

Provide DAV properties of collections (directories) and resources (files). 
These include 'live' properties (those stored as part of the file-system, e.g.
CDT, RDT) and 'dead' properties (those provided by clients and stored as XML in
the meta-data).

Apparently <allprop/> is deprecated by RFC 4981.


VERSION HISTORY
---------------
25-SEP-2020  MGD  bugfix; DavPropBegin() WATCH report no reverse mapping
12-SEP-2018  MGD  bugfix; significant refactor of locking
06-SEP-2018  MGD  bugfix; DavPropLive() metadata file also needs to be read
                    for ->LockDiscovery as well as ->AllProp and ->FindProp
15-APR-2018  MGD  SS$_ABORT on ->RequestRundown
                  bugfix; DavPropDead() flush the network buffer periodically
                          (for rediculously but legally sized file it might
                          not quickly enough to prevent no-progress timeout)
                  bugfix; DavPropSearchAst() resultant name already terminated
22-JUN-2016  MGD  DavPropSearchAst() ignore ambiguous file names
                    containing an escaped ("^.") period but no type
27-SEP-2014  MGD  improve "no reverse mapping" detection and reporting
                  bugfix; DavPropEnd() ensure unused meta-data file deleted
16-JUN-2014  MGD  DavPropSearchAst() meta file subdirectory detect and suppress
06-JUN-2013  MGD  bugfix; DavPropSearchAst() on non-ODS_EXTENDED platforms
                    (i.e. VAX) reset .nam$b_rsl to changed resultant length
                    or it can generate RMS$_RSL errors - check it out!
05-SEP-2009  MGD  refinements
24-JUN-2009  MGD  DavPropQuota() RFC 4331 quota properties
                  bugfix; DavPropName() XML
19-APR-2007  MGD  initial
*/
/*****************************************************************************/

#ifdef WASD_VMS_V7
#undef _VMS__V6__SOURCE
#define _VMS__V6__SOURCE
#undef __VMS_VER
#define __VMS_VER 70000000
#undef __CRTL_VER
#define __CRTL_VER 70000000
#endif

/* standard C header files */
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

/* VMS related header files */
#include <atrdef.h>
#include <descrip.h>
#include <dvidef.h>
#include <fibdef.h>
#include <iodef.h>
#include <libdtdef.h>
#include <libdef.h>
#include <rmsdef.h>
#include <rms.h>
#include <ssdef.h>
#include <stsdef.h>
#include <uaidef.h>

/* application related header file */
#include "wasd.h"
#include "davweb.h"

#define WASD_MODULE "DAVPROP"

#define FCH$M_DIRECTORY 0x2000

#define TEST_PROP_QUOTA 0
#define _TEST_PROP_QUOTA_USERNAME "DANIEL"

/********************/
/* external storage */
/********************/

extern BOOL  WebDavQuotaEnabled;

extern char  ErrorSanityCheck[];

extern int  SysPrvMask[],
            ToLowerCase[],
            ToUpperCase[];

extern int  EfnWait,
            EfnNoWait,
            HttpdTickSecond;

extern ACCOUNTING_STRUCT  *AccountingPtr;
extern CONFIG_STRUCT  Config;
extern HTTPD_PROCESS  HttpdProcess;
extern WATCH_STRUCT  Watch;

/*****************************************************************************/
/*
This function should check for a mapping-generated error message to determine
is there were any problems.
*/ 
 
DavPropBegin (REQUEST_STRUCT *rqptr)

{
   int  status,
        Length;
   char  *sptr;
   char  Scratch [ODS_MAX_FILE_NAME_LENGTH+1];
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                 "DavPropBegin() depth:!UL !&Z", 
                 rqptr->WebDavTaskPtr->ToDepth,
                 rqptr->ParseOds.ExpFileName);

   tkptr = rqptr->WebDavTaskPtr;

   if (WATCHING (rqptr, WATCH_RESPONSE))
      WatchThis (WATCHITM(rqptr), WATCH_RESPONSE,
                 "PROPFIND!AZ !AZ depth:!UL path:!AZ",
                 rqptr->rqPathSet.WebDavNoProp ?
                    " (path set NOprop)" : "",
                 rqptr->ParseOds.ExpFileName, tkptr->ToDepth,
                 DavWebPathAccess(rqptr));

   /* always flush before no-progress timeout (at 75%) */
   tkptr->PropFindFlushAfter = Config.cfTimeout.NoProgress * 75 / 100;
   tkptr->PropFindFlushSecond = HttpdTickSecond + tkptr->PropFindFlushAfter;

   /* ensure a reverse mapping exists for the file specification */
   Scratch[0] = '\0';
   sptr = MapUrl_Map (Scratch, sizeof(Scratch),
                      rqptr->ParseOds.NamDevicePtr, 0,
                      NULL, 0, NULL, 0, NULL, 0, NULL, rqptr, NULL);

   if (!sptr[0] && sptr[1] ||
       (MATCH8(sptr,MAPURL_NO_REVERSE_PATH) &&
        strsame(sptr,MAPURL_NO_REVERSE_PATH,-1)))
   {
      if (WATCHING (rqptr, WATCH_WEBDAV))
      {
         if (!sptr[0] && sptr[1])
             WatchThis (WATCHITM(rqptr), WATCH_WEBDAV,
                        "REVERSE MAPPING !AZ error !AZ",
                        rqptr->ParseOds.NamDevicePtr, sptr+1); 
         else
         if (WATCHING (rqptr, WATCH_WEBDAV))
             WatchThis (WATCHITM(rqptr), WATCH_WEBDAV,
                        "NO REVERSE MAPPING from !AZ to URI",
                        rqptr->ParseOds.NamDevicePtr); 
      }

      rqptr->rqResponse.HttpStatus = 500;
      ErrorVmsStatus (rqptr, SS$_ABORT, FI_LI);
      DavPropEnd (rqptr);
      return;
   }

   /* default to reporting all properties */
   if (!rqptr->rqHeader.ContentLength64) tkptr->PropData.AllProp = true;

   /* take out a concurrent read lock on the resource */
   DavWebDlmEnqueue (rqptr, &tkptr->DlmSource, rqptr->ParseOds.ExpFileName,
                     NULL, false, false, DavPropBegin2, rqptr);
}

/*****************************************************************************/
/*
Entry point for AST from VMS DLM lock.
*/ 
 
DavPropBegin2 (REQUEST_STRUCT *rqptr)

{
   int  status;
   WEBDAV_DLM  *dlmptr;
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

   tkptr = rqptr->WebDavTaskPtr;
   dlmptr = &tkptr->DlmSource;

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                 "DavPropBegin2() !&S", dlmptr->LockSb.lksb$w_status);

   if (VMSnok (dlmptr->LockSb.lksb$w_status))
   {
      DavPropEnd (rqptr);
      return;
   }

   /* network writes are checked for success, fudge the first one! */
   rqptr->NetIoPtr->WriteStatus = SS$_NORMAL;

   if (rqptr->ParseOds.NamNameLength > 0 ||
       rqptr->ParseOds.NamTypeLength > 1)
   {
      /*******************/
      /* single resource */
      /*******************/

      /* any other depth is meaningless */
      tkptr->ToDepth = WEBDAV_DEPTH_ZERO;

      status = DavPropParse (rqptr);
      if (VMSnok(status))
      {
         /* HTTP status will be set from VMS status */
         ErrorVmsStatus (rqptr, status, FI_LI);
         DavPropEnd (rqptr);
         return;
      }

      if (tkptr->PropData.PropName)
         DavPropName (rqptr);
      else
         DavPropLiveAcp (rqptr);

      return;
   }

   /**************/
   /* collection */
   /**************/

   if (tkptr->ToDepth == WEBDAV_DEPTH_ZERO)
   {
      /* collection itself */
      DavPropParent (rqptr);
      return;
   }

   if (tkptr->ToDepth == WEBDAV_DEPTH_ONE)
   {
      /* collection and children, provide the parent */
      DavPropParent (rqptr);
      return;
   }

   if (tkptr->ToDepth == WEBDAV_DEPTH_INFINITY)
   {
      /* potentially too expensive! */
      DavWebResponse (rqptr, 501, 0, "Infinite depth too expensive", FI_LI);
      DavPropEnd (rqptr);
      return;
   }

   ErrorExitVmsStatus (SS$_BUGCHECK, ErrorSanityCheck, FI_LI);
}

/*****************************************************************************/
/*
As necessary, close the multistatus XML.
*/ 

DavPropEnd (REQUEST_STRUCT *rqptr)

{
   int  status;
   WEBDAV_META  *mtaptr;
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                 "DavPropEnd() !&F", &DavPropEnd);

   tkptr = rqptr->WebDavTaskPtr;

   mtaptr = &tkptr->MetaData;

   if (mtaptr->ReadOds.Fab.fab$l_sts == RMS$_CREATED &&
       mtaptr->ReadOds.DeleteOnClose)
   {
      /* meta-data file created and never updated */
      status = OdsClose (&mtaptr->ReadOds, NULL, NULL);
      if (VMSnok (status))
         ErrorNoticed (rqptr, status, mtaptr->ReadMetaName, FI_LI); 
   }

   /* if an 'empty' multistatus response was generated */
   if (!rqptr->rqResponse.HttpStatus)
   {
      rqptr->rqResponse.NoGzip = true;
      DavWebResponse207 (rqptr);
   }

   if (rqptr->rqResponse.HttpStatus == 207)
      FaoToNet (rqptr, "</D:multistatus>\n");

   DavWebEnd (rqptr);
}

/*****************************************************************************/
/*
Get the file name of the directory containing this collection and begin to
process to get it's WebDAV properties.
*/ 

DavPropParent (REQUEST_STRUCT *rqptr)

{
   int  status,
        DirectoryFileLength;
   char  DirectoryFile [ODS_MAX_FILE_NAME_LENGTH+1];
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                 "DavPropParent() !AZ", rqptr->ParseOds.NamDevicePtr);

   tkptr = rqptr->WebDavTaskPtr;

   /* get name of directory in parent */
   OdsNameOfDirectoryFile (rqptr->ParseOds.NamDevicePtr,
                           rqptr->ParseOds.NamNamePtr -
                              rqptr->ParseOds.NamDevicePtr,
                           DirectoryFile, &DirectoryFileLength);

   AuthAccessEnable (rqptr, rqptr->ParseOds.ExpFileName, AUTH_ACCESS_READ);

   if (VMSok (status = OdsFileExists (NULL, DirectoryFile)))
      OdsParse (&tkptr->SearchOds, DirectoryFile, DirectoryFileLength,
                NULL, 0, NULL, NULL, rqptr);

   AuthAccessEnable (rqptr, 0, 0);

   if (VMSnok (status))
   {
      DavWebResponse (rqptr, 404, status, "collection does not exist", FI_LI);
      DavPropEnd (rqptr);
      return;
   }

   if (VMSok (status = tkptr->SearchOds.Fab.fab$l_sts))
      status = OdsParseTerminate (&tkptr->SearchOds);

   if (VMSnok(status))
   {
      /* HTTP status will be set from VMS status */
      ErrorNoticed (rqptr, status, NULL, FI_LI);
      ErrorVmsStatus (rqptr, status, FI_LI);
      DavPropEnd (rqptr);
      return;
   }

   tkptr->PropParent = true;

   AuthAccessEnable (rqptr, 0, AUTH_ACCESS_SYSPRV);

   OdsSearch (&tkptr->SearchOds, &DavPropSearchAst, rqptr);

   AuthAccessEnable (rqptr, 0, 0);
}

/*****************************************************************************/
/*
Parse the search structure.
*/ 

int DavPropParse (REQUEST_STRUCT *rqptr)

{
   int  status;
   char  *cptr, *sptr, *zptr;
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV, "DavPropParse()");

   tkptr = rqptr->WebDavTaskPtr;

   cptr = rqptr->ParseOds.ExpFileName;
   zptr = (sptr = tkptr->SearchSpec) + sizeof(tkptr->SearchSpec);
   while (*cptr && sptr < zptr) *sptr++ = *cptr++;
   if (!(rqptr->ParseOds.NamNameLength > 0 ||
         rqptr->ParseOds.NamTypeLength > 1))
   {     
      /* no name or type was supplied with the request, wildcard it */
      for (cptr = "*.*;0"; *cptr && sptr < zptr; *sptr++ = *cptr++);
   }
   if (sptr >= zptr)
   {
      ErrorNoticed (rqptr, SS$_RESULTOVF, NULL, FI_LI);
      return (SS$_RESULTOVF);
   }
   *sptr = '\0';
   tkptr->SearchSpecLength = sptr - tkptr->SearchSpec;

   AuthAccessEnable (rqptr, rqptr->ParseOds.ExpFileName, AUTH_ACCESS_READ);

   OdsParse (&tkptr->SearchOds, tkptr->SearchSpec, tkptr->SearchSpecLength,
             NULL, 0, NULL, NULL, rqptr);

   AuthAccessEnable (rqptr, 0, 0);

   if (VMSok (status = tkptr->SearchOds.Fab.fab$l_sts))
      status = OdsParseTerminate (&rqptr->ParseOds);

   return (status);
}

/*****************************************************************************/
/*
AST function to invoke another $SEARCH call.
*/ 

DavPropSearch (REQUEST_STRUCT *rqptr)

{
   int  status;
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV, "DavPropSearch() !&F !&S",
                 &DavPropSearch, rqptr->NetIoPtr->WriteStatus);

   if (VMSnok (rqptr->NetIoPtr->WriteStatus))
   {
      /* network write has failed (as AST), bail out now */
      DavPropEnd (rqptr);
      return;
   }

   tkptr = rqptr->WebDavTaskPtr;

   if (tkptr->PropParent)
   {
      /*******************/
      /* finished parent */
      /*******************/

      tkptr->PropParent = false;

      OdsParseRelease (&tkptr->SearchOds);

      if (tkptr->ToDepth == WEBDAV_DEPTH_ZERO)
      {
         DavPropEnd (rqptr);
         return;
      }

      /******************/
      /* begin children */
      /******************/

      status = DavPropParse (rqptr);
      if (VMSnok(status))
      {
         /* HTTP status will be set from VMS status */
         ErrorVmsStatus (rqptr, status, FI_LI);
         DavPropEnd (rqptr);
         return;
      }
   }

   AuthAccessEnable (rqptr, 0, AUTH_ACCESS_SYSPRV);

   OdsSearch (&tkptr->SearchOds, &DavPropSearchAst, rqptr);

   AuthAccessEnable (rqptr, 0, 0);
}

/*****************************************************************************/
/*
AST completion routine called each time sys$search() completes.  It will 
either point to another file name found or have "no more files found" status 
(or an error!).
*/ 

DavPropSearchAst (REQUEST_STRUCT *rqptr)

{
   int  status;
   char  *cptr, *sptr;
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

#if WATCH_MOD
   HttpdCheckPriv (FI_LI);
#endif /* WATCH_MOD */

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                 "DavPropSearchAst() !&F sts:!&S stv:!&S",
                 &DavPropSearchAst,
                 rqptr->WebDavTaskPtr->SearchOds.Fab.fab$l_sts,
                 rqptr->WebDavTaskPtr->SearchOds.Fab.fab$l_stv);

   if (rqptr->RequestState >= REQUEST_STATE_ABORT)
   {
      DavPropEnd (rqptr);
      return;
   }

   tkptr = rqptr->WebDavTaskPtr;

   if (VMSnok (status = tkptr->SearchOds.Fab.fab$l_sts))
   {
      /* if its a search list treat directory not found as if file not found */
      if ((tkptr->SearchOds.Nam_fnb & NAM$M_SEARCH_LIST) && status == RMS$_DNF)
         status = RMS$_FNF;
      
      if (status == RMS$_FNF || status == RMS$_NMF)
      {
         /***************************/
         /* end of directory search */
         /***************************/

         tkptr->SearchOds.ParseInUse = false;

         DavPropEnd (rqptr);
         return;
      }

      /*************************/
      /* protection violation? */
      /*************************/

      if (status == SS$_NOPRIV || status == RMS$_PRV)
      {
         /* continue the search */
         DavPropSearch (rqptr);
         return;
      }

      /**********************/
      /* sys$search() error */
      /**********************/

      /* assume this can only happen on the first call */
      ErrorVmsStatus (rqptr, status, FI_LI);
      DavPropEnd (rqptr);
      return;
   }

   /*****************/
   /* search result */
   /*****************/

#ifndef ODS_EXTENDED
   /*
      06-JUN-2013  MGD  VAX VMS V7.3 seems to require this adjusted
                        or it generates RMS$_RSL errors (!?)
   */
   if (tkptr->SearchOds.NamTypeLength > 1)
      tkptr->SearchOds.Nam.nam$b_rsl = tkptr->SearchOds.NamVersionPtr -
                                       tkptr->SearchOds.NamDevicePtr;
   else
      tkptr->SearchOds.Nam.nam$b_rsl = tkptr->SearchOds.NamTypePtr -
                                       tkptr->SearchOds.NamDevicePtr;
#endif

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                 "!&Z", tkptr->SearchOds.NamDevicePtr);

   if (MATCH7(tkptr->SearchOds.NamNamePtr,"000000.") &&
       strsame (tkptr->SearchOds.NamNamePtr, "000000.DIR;", 11))
   {
      status = OdsReallyADir (rqptr, &tkptr->SearchOds);
      if (VMSok (status))
      {
         /* no need to report the MFD */
         DavPropSearch (rqptr);
         return;
      }
   }

   /* if a meta file directory it is not accessible */
   if (DavMetaDir (rqptr, &tkptr->SearchOds))
   {
      DavPropSearch (rqptr);
      return;
   }

   if (DavMetaFile (&tkptr->SearchOds))
   {
      DavPropSearch (rqptr);
      return;
   }

   /* in true Unix-style "hidden" files do not appear (those beginning ".") */
   if (SAME1(tkptr->SearchOds.NamNamePtr,'.') ||
       SAME2(tkptr->SearchOds.NamNamePtr,'^.'))
   {
      /* except in demo mode or to VMS authenticated and profiled requests */
      if (rqptr->rqPathSet.WebDavNoHidden)
      {
         if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
            WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV, ".FILE (hidden)");
         DavPropSearch (rqptr);
         return;
      }
   }

   if (tkptr->SearchOds.NamTypeLength <= 1)
   {
      /* no explicit type - look to see if name contains escaped period */
      for (cptr = tkptr->SearchOds.NamNamePtr;
           cptr < tkptr->SearchOds.NamTypePtr;
           cptr++)
         if (*(USHORTPTR)cptr == '^.') break;
      if (cptr < tkptr->SearchOds.NamTypePtr)
      {
         /* escaped period - do not list these ambiguous file names */
         if (WATCHING (rqptr, WATCH_WEBDAV))
            WatchThis (WATCHITM(rqptr), WATCH_WEBDAV,
                       "^.NAME.; !AZ", tkptr->SearchOds.NamNamePtr);
         DavPropSearch (rqptr);
         return;
      }
   }

   /**************/
   /* properties */
   /**************/

   if (tkptr->PropData.PropName)
      DavPropName (rqptr);
   else
      DavPropLiveAcp (rqptr);
}

/*****************************************************************************/
/*
Provide the <propname/> property (all property names without values).
*/

DavPropName (REQUEST_STRUCT *rqptr)

{
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV, "DavPropName()");

   tkptr = rqptr->WebDavTaskPtr;

   DavWebHref (rqptr, tkptr->SearchOds.NamDevicePtr, 0);

   if (!rqptr->rqResponse.HttpStatus) DavWebResponse207 (rqptr);

   FaoToNet (rqptr,
" <D:response>\n\
  <D:href>!AZ!&%AZ</D:href>\n\
  <D:propstat>\n\
   <D:status>HTTP/1.1 200 OK</D:status>\n\
   <D:prop>\n\
    <creationdate/>\n\
    <displayname/>\n\
    <getlastmodified/>\n\
    <getcontentlanguage/>\n\
    <getcontentlength/>\n\
    <getcontenttype/>\n\
    <getetag/>\n\
    <resourcetype/>\n\
    <source/>\n",
             tkptr->HrefHost,
             tkptr->PropParent ?
                rqptr->rqHeader.PathInfoPtr : tkptr->HrefPath);

   if (tkptr->LockingEnabled)
      FaoToNet (rqptr,
"    <lockdiscovery/>\n\
    <supportedlock/>\n");

   if (tkptr->QuotaEnabled)
      FaoToNet (rqptr,
"    <quota-available-bytes/>\n\
    <quota-used-bytes/>\n");

   FaoToNet (rqptr,
"   </D:prop>\n\
  </D:propstat>\n\
 </D:response>\n");

   DavPropEnd (rqptr);
}

/*****************************************************************************/
/*
Using the ACP-QIO interface obtain the live file properties (size, created
date/time, last modified, etc.)
*/

DavPropLiveAcp (REQUEST_STRUCT *rqptr)

{
   int  status;
   char  *cptr;
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV, "DavPropLiveAcp() !AZ",
                 rqptr->WebDavTaskPtr->SearchOds.NamDevicePtr);

   tkptr = rqptr->WebDavTaskPtr;

   AuthAccessEnable (rqptr, tkptr->SearchOds.NamDevicePtr, AUTH_ACCESS_READ);

   OdsFileAcpInfo (&tkptr->SearchOds, &DavPropLive, rqptr); 

   AuthAccessEnable (rqptr, 0, 0);
}

/****************************************************************************/
/*
AST called from OdsFileAcpInfo() (invoked by DavPropLiveAcp()) when ACP QIO
completes.  This function supplies the 'live' properties associated with a file
(or directory file).
*/ 

DavPropLive (REQUEST_STRUCT *rqptr)

{
   int  status,
        Bytes,
        NameLength;
   unsigned long  AllocatedVbn,
                  EndOfFileVbn;
   char  *cptr, *sptr, *zptr;
   char  DateTime [32],
         EntityTag [32],
         FileSpec [ODS_MAX_FILE_NAME_LENGTH+1];
   WEBDAV_PROP  *proptr;
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

#if WATCH_MOD
   HttpdCheckPriv (FI_LI);
#endif /* WATCH_MOD */

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                 "DavPropLive() !&F !&S", &DavPropLive,
                 rqptr->WebDavTaskPtr->SearchOds.FileQio.IOsb.Status);

   tkptr = rqptr->WebDavTaskPtr;
   proptr = &tkptr->PropData;

   /* first deassign the channel allocated by OdsFileAcpInfo() */
   sys$dassgn (tkptr->SearchOds.FileQio.AcpChannel);

   if ((status = tkptr->SearchOds.FileQio.IOsb.Status) == SS$_NOSUCHFILE)
      status = RMS$_FNF;

   if (VMSnok (status)) 
   {
      /****************/
      /* error status */
      /****************/

      if (tkptr->ToDepth == WEBDAV_DEPTH_ZERO)
      {
         /* just the single resource */
         ErrorVmsStatus (rqptr, status, FI_LI);
         DavPropEnd (rqptr);
         return;
      }

      /*************************/
      /* protection violation? */
      /*************************/

      if (status == SS$_NOPRIV || status == RMS$_PRV)
      {
         DavPropSearch (rqptr);
         return;
      }

      /*******************/
      /* something else! */
      /*******************/

      DavWebMultiStatus (rqptr, status, tkptr->SearchOds.ExpFileName);
      DavPropEnd (rqptr);
      return;
   }

   if (!rqptr->rqResponse.HttpStatus) DavWebResponse207 (rqptr);

   /**********/
   /* report */
   /**********/

   /* same status as OdsReallyADir() */
   if (tkptr->SearchOds.FileQio.AtrUchar & FCH$M_DIRECTORY)
   {
      tkptr->SearchIsDirectory = true;
      status = SS$_NORMAL;
   }
   else
   {
      tkptr->SearchIsDirectory = false;
      status = SS$_ABORT;
   }

   DavWebHref (rqptr, tkptr->SearchOds.NamDevicePtr, status);

   FaoToNet (rqptr,
" <D:response>\n\
  <D:href>!AZ!&%AZ</D:href>\n\
  <D:propstat>\n\
   <D:status>HTTP/1.1 200 OK</D:status>\n\
   <D:prop>\n",
             tkptr->HrefHost,
             tkptr->PropParent ?
                rqptr->rqHeader.PathInfoPtr : tkptr->HrefPath);

   if (proptr->AllProp || proptr->DisplayName)
   {
      /********/
      /* name */
      /********/

      if (tkptr->PropParent)
         zptr = cptr = "";
      else
      {
         /* resolve the name from the href path */
         for (cptr = sptr = tkptr->HrefPath; *cptr; cptr++);
         zptr = cptr;
         while (cptr > sptr && *cptr != '/') cptr--;
         if (tkptr->SearchIsDirectory)
         {
            if (cptr > sptr && *cptr == '/')
            {
               cptr--;
               zptr--;
            }
            while (cptr > sptr && *cptr != '/') cptr--;
         }
         if (*cptr == '/') cptr++;
      }

      FaoToNet (rqptr,
"     <D:displayname>!#&;AZ</D:displayname>\n",
                zptr-cptr, cptr);
   }

   if (proptr->AllProp || proptr->ResourceType)
   {
      /******************/
      /* file/directory */
      /******************/

      if (tkptr->SearchIsDirectory)
         FaoToNet (rqptr,
"     <D:resourcetype><D:collection/></D:resourcetype>\n");
      else
         FaoToNet (rqptr, "     <D:resourcetype/>\n");
   }

   if (proptr->AllProp || proptr->CreationDate)
   {
      /***********/
      /* created */
      /***********/

      /* this property format is "1995-0825T17:32:40Z" */
      DavWebDateTimeTo3339 (DateTime, &tkptr->SearchOds.FileQio.CdtTime64);
      FaoToNet (rqptr,
"     <D:creationdate>!AZ</D:creationdate>\n",
                DateTime);
   }

   if (proptr->AllProp || proptr->GetContentLanguage)
      /* WASD dosn't handle this datum */
      FaoToNet (rqptr,
"     <D:getcontentlanguage/>\n");

   if (proptr->AllProp || proptr->GetContentLength)
   {
      /******************/
      /* content length */
      /******************/

      if (!tkptr->SearchIsDirectory)
      {
         AllocatedVbn =
((tkptr->SearchOds.FileQio.RecAttr.fat$l_hiblk & 0xffff) << 16) |
((tkptr->SearchOds.FileQio.RecAttr.fat$l_hiblk & 0xffff0000) >> 16);
         EndOfFileVbn =
((tkptr->SearchOds.FileQio.RecAttr.fat$l_efblk & 0xffff) << 16) |
((tkptr->SearchOds.FileQio.RecAttr.fat$l_efblk & 0xffff0000) >> 16);

         if (EndOfFileVbn <= 1)
            Bytes = tkptr->SearchOds.FileQio.RecAttr.fat$w_ffbyte;
         else
            Bytes = ((EndOfFileVbn-1) << 9) +
                    tkptr->SearchOds.FileQio.RecAttr.fat$w_ffbyte;

         if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
            WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
               "AllocatedVbn:!UL EndOfFileVbn:!UL FirstFreeByte:!UL Bytes;!UL",
               AllocatedVbn, EndOfFileVbn,
               tkptr->SearchOds.FileQio.RecAttr.fat$w_ffbyte,
               Bytes);

         FaoToNet (rqptr,
"     <D:getcontentlength>!UL</D:getcontentlength>\n",
                   Bytes);
      }
   }

   if (proptr->AllProp || proptr->GetContentType)
   {
      /****************/
      /* content type */
      /****************/

      if (tkptr->SearchIsDirectory)
         cptr = "httpd/unix-directory";
      else
      {
         if (rqptr->PathOds == MAPURL_PATH_ODS_ADS ||
             rqptr->PathOds == MAPURL_PATH_ODS_SMB)
            cptr = MapOdsAdsFileType (tkptr->SearchOds.NamTypePtr);
         else
         if (rqptr->PathOds == MAPURL_PATH_ODS_SRI)
            cptr = MapOdsSriFileType (tkptr->SearchOds.NamTypePtr);
         else
            cptr = tkptr->SearchOds.NamTypePtr;
         ConfigContentType (&tkptr->ContentInfo, cptr);
         cptr = tkptr->ContentInfo.ContentTypePtr;
         /* transmogrify WASD internal types */
         if (SAME2(cptr,'x-') || SAME2(cptr,'X-'))
            cptr = "application/octet-stream";
      }

      FaoToNet (rqptr,
"     <D:getcontenttype>!AZ</D:getcontenttype>\n",
                cptr);
   }

   if (proptr->AllProp || proptr->GetEtag)
   {
      /********/
      /* etag */
      /********/

      FileGenerateEntityTag (EntityTag, &tkptr->SearchOds.FileQio);
      FaoToNet (rqptr,
"     <D:getetag>\"!AZ\"</D:getetag>\n",
                EntityTag);
   }

   if (proptr->AllProp || proptr->GetLastModified)
   {
      /*****************/
      /* last modified */
      /*****************/

      /* this property format is "Fri, 25 Aug 1995 17:32:40 GMT" */
      HttpGmTimeString (DateTime, &tkptr->SearchOds.FileQio.RdtTime64);
      FaoToNet (rqptr,
"     <D:getlastmodified>!AZ</D:getlastmodified>\n",
                DateTime);
   }

#if TEST_PROP_QUOTA
   WebDavQuotaEnabled = proptr->QuotaUsedBytes =
      proptr->QuotaAvailableBytes = true;
#endif

   if (WebDavQuotaEnabled)
      if (proptr->QuotaUsedBytes || proptr->QuotaAvailableBytes)
         DavPropQuota (rqptr);

   if (tkptr->LockingEnabled &&
       (proptr->AllProp || proptr->LockDiscovery))
   {
      /*********************/
      /* locking available */
      /*********************/

      FaoToNet (rqptr,
"     <D:supportedlock>\n\
      <D:lockentry>\n\
       <D:lockscope><D:exclusive/></D:lockscope>\n\
       <D:locktype><D:write/></D:locktype>\n\
      </D:lockentry>\n\
      <D:lockentry>\n\
       <D:lockscope><D:shared/></D:lockscope>\n\
       <D:locktype><D:write/></D:locktype>\n\
      </D:lockentry>\n\
     </D:supportedlock>\n");
   }

   if (tkptr->MicrosoftAgent &&
       rqptr->rqPathSet.WebDavNoWinProp &&
       (proptr->AllProp || proptr->FindProp))
   {
      /******************************/
      /* fudge Microsoft properties */
      /******************************/

      /* these property formats are "Fri, 25 Aug 1995 17:32:40 GMT" */
      HttpGmTimeString (DateTime, &tkptr->SearchOds.FileQio.CdtTime64);
      FaoToNet (rqptr,
"     <MS:Win32CreationTime xmlns:MS=\"urn:schemas-microsoft-com:\">\
!AZ</MS:Win32CreationTime>\n",
                DateTime);

      HttpGmTimeString (DateTime, &tkptr->SearchOds.FileQio.RdtTime64);
      FaoToNet (rqptr,
"     <MS:Win32LastModifiedTime xmlns:MS=\"urn:schemas-microsoft-com:\">\
!AZ</MS:Win32LastModifiedTime>\n",
                DateTime);

      /* NOT the last access time but what the hey it's a fudge! */
      FaoToNet (rqptr,
"     <MS:Win32LastAccessTime xmlns:MS=\"urn:schemas-microsoft-com:\">\
!AZ</MS:Win32LastAccessTime>\n",
                DateTime);

      /* apparently it is good practice to always set the archive bit */
      FaoToNet (rqptr,
"     <MS:Win32FileAttributes xmlns:MS=\"urn:schemas-microsoft-com:\">\
00000020</MS:Win32FileAttributes>\n");
   }

   tkptr->MetaData.VmsStatus = 0;

   if (rqptr->rqPathSet.WebDavNoProp)
      DavPropDead (rqptr);
   else
   if (proptr->AllProp || proptr->FindProp || proptr->LockDiscovery)
   {
      /*************/
      /* meta-data */
      /*************/

      if (tkptr->ToDepth == WEBDAV_DEPTH_ZERO)
      {
         /*
            The collection itself.
            Do NOT use DavPropParent() non-concealed specification to
            access the meta-data.  Use the original request specification.
         */
         DavMetaRead (rqptr, &tkptr->MetaData, rqptr->ParseOds.NamDevicePtr,
                      &DavPropDead, rqptr);
         return;
      }

      zptr = (sptr = FileSpec) + sizeof(FileSpec)-1;
      cptr = tkptr->SearchOds.NamDevicePtr;
      if (tkptr->SearchOds.FileQio.AtrUchar & FCH$M_DIRECTORY)
      {
         /* munge the ]NAME.DIR into a directory specification .NAME] */
         while (*cptr && cptr < tkptr->SearchOds.NamNamePtr-1 && sptr < zptr)
            *sptr++ = *cptr++;
         if (sptr < zptr) *sptr++ = '.';
         if (*cptr) cptr++;
         while (*cptr && cptr < tkptr->SearchOds.NamTypePtr && sptr < zptr)
            *sptr++ = *cptr++;
         if (sptr < zptr) *sptr++ = ']';
      }
      else
      {
         /* just a POF */
         while (*cptr && cptr < tkptr->SearchOds.NamVersionPtr && sptr < zptr)
            *sptr++ = *cptr++;
      }
      *sptr = '\0';

      DavMetaRead (rqptr, &tkptr->MetaData, FileSpec, &DavPropDead, rqptr);
   }
   else
      DavPropDead (rqptr);
}

/*****************************************************************************/
/*
AST called from DavMetaRead() (invoked by DavPropLive()), or called directly
from DavPropLive().  This function supplies the 'dead' properties assocated
with a file (or directory).  These properties are stored in the meta-data and
accessed as required.
*/ 
 
DavPropDead (REQUEST_STRUCT *rqptr)
{
   int  status;
   STR_DSC  *fdptr, *sdptr;
   WEBDAV_META  *mtaptr;
   WEBDAV_PROP  *proptr;
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                 "DavPropDead() !&S",
                 rqptr->WebDavTaskPtr->MetaData.VmsStatus);

   tkptr = rqptr->WebDavTaskPtr;
   mtaptr = &tkptr->MetaData;
   proptr = &tkptr->PropData;

   if (VMSok (tkptr->MetaData.VmsStatus))
   {
      if (tkptr->LockingEnabled &&
          (proptr->AllProp || proptr->LockDiscovery))
      {
         /* what locking is available */
         DavLockDiscovery (rqptr);
      }

      if (proptr->AllProp)
      {
         /* list all of the 'dead' properties */
         STR_DSC_ITERATE (sdptr, &tkptr->MetaData.PropDsc)
            if (STR_DSC_LEN(sdptr))
               FaoToNet (rqptr, "     !AZ\n", STR_DSC_PTR(sdptr));
      }
      else
      if (proptr->FindProp)
      {
         /* search for requested properties and report any found */
         STR_DSC_ITERATE (sdptr, &tkptr->XmlData.PropFindDsc)
            if (fdptr = DavMetaSearch (rqptr, &tkptr->MetaData.PropDsc, sdptr))
               if (STR_DSC_LEN(fdptr))
                  FaoToNet (rqptr, "     !AZ\n", STR_DSC_PTR(fdptr));
      }
   }

   FaoToNet (rqptr,
"   </D:prop>\n\
  </D:propstat>\n\
 </D:response>\n");

   if (tkptr->ToDepth == WEBDAV_DEPTH_ZERO)
      DavPropEnd (rqptr);
   else
   if (tkptr->PropFindFlushSecond <= HttpdTickSecond)
   {
      /* no output for this period so let's force a flush */
      tkptr->PropFindFlushSecond = HttpdTickSecond +
                                   tkptr->PropFindFlushAfter;
      NetWriteBuffered (rqptr, DavPropSearch, NULL, 0);
   }
   else
   {
      /* reset flush timer if the buffer was at the last attempt */
      if (STR_DSC_LEN(&rqptr->NetWriteBufferDsc) < tkptr->PropFindFlushLength)
         tkptr->PropFindFlushSecond = HttpdTickSecond +
                                      tkptr->PropFindFlushAfter;
      /* set the current length of the buffer */
      tkptr->PropFindFlushLength = STR_DSC_LEN(&rqptr->NetWriteBufferDsc);
      /* flush if buffer full(ish) */
      NetWriteBuffered (rqptr, DavPropSearch, NULL, -1);
   }
}

/*****************************************************************************/
/*
Implement the PROPPATCH method.  Modfiy the meta-data properties.
*/ 
 
DavPropPatchBegin (REQUEST_STRUCT *rqptr)

{
   STR_DSC  *sdptr;
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                 "DavPropPatchBegin() !&Z",  rqptr->ParseOds.ExpFileName);

   if (!rqptr->RemoteUser[0])
   {
      DavWebResponse (rqptr, 403, SS$_BUGCHECK, "RemoteUser?", FI_LI);
      DavWebEnd (rqptr);
      return;
   }

   tkptr = rqptr->WebDavTaskPtr;

   if (rqptr->rqPathSet.WebDavNoProp)
   {
      if (WATCHING (rqptr, WATCH_WEBDAV))
         WatchThis (WATCHITM(rqptr), WATCH_WEBDAV,
                    "PROPPATCH (path set NOprop) !AZ",
                    rqptr->ParseOds.ExpFileName);
      DavPropPatchEnd (rqptr);
      return;
   }

   if (tkptr->MicrosoftAgent &&
       rqptr->rqPathSet.WebDavNoWinProp)
   {
      /* step through each property in the request body */
      STR_DSC_ITERATE (sdptr, &tkptr->XmlData.PropSetDsc)
      {
         if (!STR_DSC_LEN(sdptr)) continue;
         if (strstr(STR_DSC_PTR(sdptr),"urn:schemas-microsoft-com:")) continue;
         /* break on the first non-MS property */
         break;
      }
      if (!sdptr)
      {
         /* no properties (unlikely) or all MS properties (almost certainly) */
         if (WATCHING (rqptr, WATCH_WEBDAV))
            WatchThis (WATCHITM(rqptr), WATCH_WEBDAV,
                       "PROPPATCH (path set NOWINPROP) !AZ",
                       rqptr->ParseOds.ExpFileName);
         tkptr->MetaData.VmsStatus = SS$_NORMAL;
         DavPropPatchEnd (rqptr);
         return;
      }
      /* otherwise drop thru to continue */
   }

   tkptr->TestLockState = 0;

   DavPropPatchBegin2 (rqptr);
}

/*****************************************************************************/
/*
Asynchronously test for locking then if not begin the patching.
*/ 
 
DavPropPatchBegin2 (REQUEST_STRUCT *rqptr)

{
   int  status;
   char  *cptr;
   WEBDAV_META  *mtaptr;
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

   tkptr = rqptr->WebDavTaskPtr;
   mtaptr = &tkptr->MetaData;

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                 "DavPropPatchBegin2() !&F !UL",
                 DavPropPatchBegin2, tkptr->TestLockState);

   if (tkptr->SearchOds.NamDeviceLength)
      cptr = tkptr->SearchOds.ExpFileName;
   else
   if (rqptr->ParseOds.NamDeviceLength)
      cptr = rqptr->ParseOds.ExpFileName;
   else
      ErrorExitVmsStatus (SS$_BUGCHECK, ErrorSanityCheck, FI_LI);

   /***********/
   /* locking */
   /***********/

   switch (tkptr->TestLockState)
   {
      case 0 :

         /* establish a request (overall) VMS DLM lock on source */
         tkptr->TestLockState++;
         DavWebDlmEnqueue (rqptr, &tkptr->DlmSource,
                           rqptr->ParseOds.ExpFileName,
                           NULL, true, false,
                           DavPropPatchBegin2, rqptr);
         return;

      case 1 :

         if (VMSnok (status = tkptr->DlmSource.LockSb.lksb$w_status))
         {
            /* ordinarily shouldn't return any errors */
            DavWebResponse (rqptr, 500, status, NULL, FI_LI);
            DavPropPatchEnd (rqptr);
            return;
         }

         /* check for meta-lock on existing source */
         tkptr->TestLockState++;
         DavLockTest (rqptr, rqptr->ParseOds.ExpFileName, false,
                      DavPropPatchBegin2, rqptr);
         return;

      case 2 :

         if (VMSnok (tkptr->TestLockStatus))
         {
            mtaptr->VmsStatus = tkptr->TestLockStatus;
            DavWebResponse (rqptr, 423, 0, "source locked", FI_LI);
            DavPropPatchEnd (rqptr);
            return;
         }
   }

   /**************/
   /* not locked */
   /**************/

   if (WATCHING (rqptr, WATCH_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_WEBDAV, "PROPPATCH !AZ", cptr);

   DavMetaLock (rqptr, &tkptr->MetaData, rqptr->ParseOds.ExpFileName,
                &DavPropPatchUpdate, &tkptr->MetaData);
}

/*****************************************************************************/
/*
*/ 
 
DavPropPatchUpdate (WEBDAV_META *mtaptr)

{
   int  status;
   REQUEST_STRUCT  *rqptr;

   /*********/
   /* begin */
   /*********/

   rqptr = mtaptr->RequestPtr;

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                 "DavPropPatchUpdate() !&F !&S",
                 DavPropPatchUpdate, mtaptr->VmsStatus);

   if (VMSok (mtaptr->VmsStatus))
      DavMetaUpdate (mtaptr, DavPropPatchEnd, rqptr);
   else
      DavPropPatchEnd (rqptr);
}

/*****************************************************************************/
/*
Complete a PROPPATCH request.
*/ 
 
DavPropPatchEnd (REQUEST_STRUCT *rqptr)

{
   int  status, xmlsts;
   char  *cptr;
   WEBDAV_META  *mtaptr;
   WEBDAV_TASK  *tkptr;

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV, "DavPropPatchEnd()");

   tkptr = rqptr->WebDavTaskPtr;
   mtaptr = &tkptr->MetaData;

   if (VMSok (mtaptr->VmsStatus))
   {
      rqptr->rqResponse.NoGzip = true;
      DavWebResponse207 (rqptr);

      DavWebHref (rqptr, rqptr->ParseOds.ExpFileName, 0);

      FaoToNet (rqptr,
" <D:response>\n\
   <D:href>!AZ!&%AZ</D:href>\n\
 </D:response>\n\
</D:multistatus>\n",
                tkptr->HrefHost,
                tkptr->PropParent ?
                   rqptr->rqHeader.PathInfoPtr : tkptr->HrefPath);
   }
   else
   {
      if (mtaptr->VmsStatus == SS$_ACCONFLICT)
      {
         /* resource is locked */
         DavWebResponse (rqptr, 423, 0, NULL, FI_LI);
      }
      else
      {
         /* other reason for failure */
         DavWebResponse (rqptr, 500, mtaptr->VmsStatus, NULL, FI_LI);
      }
   }

   DavWebEnd (rqptr);
}

/*****************************************************************************/
/*
Provide RFC 4331 quota properties (all synchronous).

If the path access is SET webdav=server attempt to return any disk quota for
the HTTPd server account or if SET webdav=profile the SYSUAF authenticated
request's VMS username.  Both of these require a $GETUAI to obtain the UIC.  If
neither of these (or if the $GETUAI fails for some reason) then return the
request path's device used and available space.
*/

DavPropQuota (REQUEST_STRUCT *rqptr)

{
   static unsigned long  AddendZero = 0,
                         FiveTwelve = 512,
                         UaiContext = -1;
   static unsigned long  DviFreeBlocks,
                         DviMaxBlock,
                         UaiUic;

   static char  UserName [12+1];
   static int  UserNameLength;
   static $DESCRIPTOR (UserNameDsc, UserName);

   static VMS_ITEM_LIST2  DeviceFibDsc,
                          InQuotaDsc,
                          OutQuotaDsc;

   static VMS_ITEM_LIST3 
   UaiItems [] = 
   {
      { sizeof(UaiUic), UAI$_UIC, &UaiUic, 0 },
      { 0,0,0,0 }
   },
   BlocksItemList [] = 
   {
      { sizeof(DviMaxBlock), DVI$_MAXBLOCK, &DviMaxBlock, 0 },
      { sizeof(DviFreeBlocks), DVI$_FREEBLOCKS, &DviFreeBlocks, 0 },
      { 0, 0, 0, 0 }
   };

   int  status;
   unsigned short  DeviceChannel,
                   OutLength;
   unsigned long  BytesAvailable,
                  BytesUsed;
   uint64  bytes64;
   $DESCRIPTOR (DeviceDsc, "");
   struct fibdef  DeviceFib; 

   WEBDAV_PROP  *proptr;
   WEBDAV_TASK  *tkptr;

   struct {
      unsigned long flags;
      unsigned long uic;
      unsigned long used;
      unsigned long perm;
      unsigned long over;
      unsigned long unused[3];
   } InQuota, OutQuota;

   struct {
      unsigned short  iosb$w_status;
      unsigned short  iosb$w_bcnt;
      unsigned long  iosb$l_reserved;
   } IOsb;

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV, "DavPropQuota()");

   tkptr = rqptr->WebDavTaskPtr;
   proptr = &tkptr->PropData;

   DeviceDsc.dsc$a_pointer = rqptr->ParseOds.NamDevicePtr;
   DeviceDsc.dsc$w_length = rqptr->ParseOds.NamDeviceLength;

   if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
      WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV, "!#AZ",
               DeviceDsc.dsc$w_length, DeviceDsc.dsc$a_pointer);

   status = sys$assign (&DeviceDsc, &DeviceChannel, 0, 0);
   if (VMSnok (status))
   {
      if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
         WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                    "sys$assign() !&S", status);
      return (status);
   }

   UserNameDsc.dsc$a_pointer = NULL;
   if (rqptr->rqPathSet.WebDavServer)
   {
      /* try to check HTTPd server account quota */
      UserNameDsc.dsc$a_pointer = HttpdProcess.UserName;
      UserNameDsc.dsc$w_length = HttpdProcess.UserNameLength;
   }
   else
   if (rqptr->rqPathSet.WebDavProfile)
   {
      /* try to check SYSUAF authenticated user account quota */
      if (rqptr->rqAuth.SysUafAuthenticated &&
          rqptr->rqAuth.VmsUserProfileLength)
      {
         UserNameDsc.dsc$a_pointer = rqptr->RemoteUser;
         UserNameDsc.dsc$w_length = rqptr-> RemoteUserLength;
      }
   }

#if TEST_PROP_QUOTA
#ifdef TEST_PROP_QUOTA_USERNAME
   UserNameDsc.dsc$a_pointer = TEST_PROP_QUOTA_USERNAME;
   UserNameDsc.dsc$w_length = strlen(TEST_PROP_QUOTA_USERNAME);
#endif
#endif

   status = 0;

   if (UserNameDsc.dsc$a_pointer)
   {
      /****************/
      /* username UIC */
      /****************/

      if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
         WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV, "{!UL}!#AZ !&Z",
                    UserNameDsc.dsc$w_length, UserNameDsc.dsc$w_length,
                    UserNameDsc.dsc$a_pointer, UserName);

      if (UserNameLength != UserNameDsc.dsc$w_length ||
          strncmp (UserName, UserNameDsc.dsc$a_pointer, UserNameLength))
      {
         /* buffer the username (and consequently the UIC) */
         char  *cptr, *sptr, *zptr;
         zptr = (sptr = UserName) + sizeof(UserName)-1;
         for (cptr = UserNameDsc.dsc$a_pointer;
              cptr < UserNameDsc.dsc$a_pointer + UserNameDsc.dsc$w_length;
              *sptr++ = *cptr++);
         *sptr = '\0';
         UserNameLength = sptr - UserName;

         UserNameDsc.dsc$a_pointer = UserName;
         UserNameDsc.dsc$w_length = UserNameLength;

         sys$setprv (1, &SysPrvMask, 0, 0);
         status = sys$getuai (0, &UaiContext, &UserNameDsc, &UaiItems,
                              0, 0, 0);
         sys$setprv (0, &SysPrvMask, 0, 0);

         if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
            WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                       "sys$getuai() !&S", status);
      }
      else
         status = SS$_NORMAL;
   }

   /* if UIC was successfully retrieved */
   if (VMSok (status))
   {
      /********************/
      /* check disk quota */
      /********************/

      memset (&DeviceFib, 0, sizeof(DeviceFib));
      DeviceFib.fib$w_exctl = FIB$C_EXA_QUOTA;
      DeviceFibDsc.buf_len = sizeof(DeviceFib);
      DeviceFibDsc.buf_addr = &DeviceFib;

      memset (&InQuota, 0, sizeof(InQuota));
      InQuotaDsc.buf_len = sizeof(InQuota);
      InQuotaDsc.buf_addr = &InQuota;
      InQuota.uic = UaiUic;

      memset (&OutQuota, 0, sizeof(OutQuota));
      OutQuotaDsc.buf_len = sizeof(OutQuota);
      OutQuotaDsc.buf_addr = &OutQuota;

      status = sys$qiow (0, DeviceChannel, IO$_ACPCONTROL, &IOsb, 0, 0,
                         &DeviceFibDsc, &InQuotaDsc, &OutLength, &OutQuotaDsc,
                         0, 0);

      if (VMSok (status)) status = IOsb.iosb$w_status;
      if (VMSok (status))
      {
         BytesAvailable = OutQuota.perm - OutQuota.used;
         BytesUsed = OutQuota.used;
         if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
            WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                       "QUOTA perm:!UL used:!UL",
                       OutQuota.perm, OutQuota.used);
      }
      else
      if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
         WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                    "sys$qiow() !&S", status);
   }

   /* if the quota ACP failed or if quota not checked */
   if (VMSnok (status))
   {
      /********************/
      /* get device usage */
      /********************/
                                                
      status = sys$getdviw (EfnWait, DeviceChannel, 0,
                            &BlocksItemList, &IOsb, 0, 0, 0);

      if (VMSok (status)) status = IOsb.iosb$w_status;
      if (VMSok (status))
      {
         BytesAvailable = DviFreeBlocks;
         BytesUsed = DviMaxBlock - DviFreeBlocks;
         if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
            WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                       "BLOCKS max:!UL free:!UL", DviMaxBlock, DviFreeBlocks);
      }
      else
      if (WATCHMOD (rqptr, WATCH_MOD_WEBDAV))
         WatchThis (WATCHITM(rqptr), WATCH_MOD_WEBDAV,
                    "sys$qiow() !&S", status);
   }

   if (VMSok (status))
   {
      /***************/
      /* list quotas */
      /***************/

      if (proptr->QuotaUsedBytes)
      {
         status = lib$emul (&FiveTwelve, &BytesUsed,
                            &AddendZero, &bytes64);
         if (VMSok (status))
            FaoToNet (rqptr,
"     <D:quota-used-bytes>!@SQ</D:quota-used-bytes>\n",
                      &bytes64);
         else
            ErrorNoticed (rqptr, status, NULL, FI_LI);
      }

      if (proptr->QuotaAvailableBytes)
      {
         status = lib$emul (&FiveTwelve, &BytesAvailable,
                            &AddendZero, &bytes64);
         if (VMSok (status))
            FaoToNet (rqptr,
"     <D:quota-available-bytes>!@SQ</D:quota-available-bytes>\n",
                      &bytes64);
         else
            ErrorNoticed (rqptr, status, NULL, FI_LI);
      }
   }

   sys$dassgn (DeviceChannel);

   return (status);
}

/*****************************************************************************/