1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 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 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425
|
* * * Modules for FoxEye: principles * * *
Preamble.
---------
All modules have the same interface - initialisation via ModuleInit()
function, destroying via the signal S_TERMINATE. When module going
to unload, all binds that were made on init must be deleted. Note:
because module is being initialised on startup, neither listfile is
loaded yet nor Wtmp is ready to get any events so don't use them on
module initialization.
Files in the module source: *.c, *.h - to compile, never installed;
*.help - will be installed to help directory without last name part
(i.e.".help"); accvs.m4, accvs.api, accvs.cfg and accvs.POTFILES -
additions to main configure.in, doc/modules.api, core/foxeye.h and
po/POTFILES.in, for Git only, are not distributable.
Module have to have one or more of: interface, bind table, binding, or
script interface. See descriptions below for ones.
Each module is fully independent part with own functionality that may
be written on any programming language. Module interoperable with
other modules and core only via this API and any module CANNOT rely
on any functionality beyond of this API. If you found something from
existing code and that isn't stated in this document then be sure it
may be changed in the future and it WILL be changed even. And if you
think you cannot do something without a hack then you just don't know
yet that you can do it without any hacks. Enjoy! :)
What is an interface.
--------------------
The interface is part of code what communicate with some resource(s).
This may be: log file, session, IRC channel, another bot, etc. Each
interface has appropriated INTERFACE structure that contains all data
of that interface. Each interface may have two functions, one for
requests (data message for interface), and one for signals (simple
commands for interface to do something: shutdown, flush buffers, user
programmed function, stop, etc.). If both of those functions are not
set then this interface is considered as clone and in this case
'prev' member of interface structure should be set to main interface.
Another case when 'prev' member of interface structure is set is when
you nesting some other interface locking previous and in that case
you should set both signal function and request function. Case when
there is no main interface for a clone is undefined and you should
never create such interfaces. Data of the interface structure may be
accessed only from bindings, from request function, or from signal
function. To access data from threads you must lock dispatcher first
(by calling Set_Iface() function). When you want to terminate some
interface then you have to either send S_TERMINATE signal to it or
set I_FINWAIT flag on it and dispatcher will terminate it by sending
S_TERMINATE signal to it shortly. When interface has finished its job
it has to set I_DIED flag on it within the same thread that called
function Add_Iface() before. After that you CANNOT access any field
of INTERFACE structure! As soon as I_DIED flag is set this interface
will never get any signals or requests but some other things will be
done by dispatcher:
- any requests to it will be purged;
- interface and his clones (if there are any) will be deleted from
dispatcher;
- 'data' member of the interface structure will be freed;
- if that interface was nested then previous (stopped) interface will
be awaken;
- if that interface has nested interfaces then every of them will get
S_TERMINATE signal;
What is a bind table.
-------------------
The bind table is check table contains one or more bindings what can
be checked for matching input string. Each bind table can be checked
with only bot interface and must contain bindings one type and one
purpose. In other words, when some event happens then bind table
will be checked for matching to some key. Bind table there is a list
of bindings for exactly one type of events.
What is a binding.
----------------
The binding consist of string to match and bound function. When some
input is matched to string, bound function is called. In other words,
binding is key and function to react on some event (see description
of bind table above). Bindings can be of two types: binary (which
have interaction through C function call) and scripting (through some
interpreter module, see documentation). Each type of bindings have
own set of parameters and return values, see below.
Client records in listfile. Names convention.
------------------------------------------
There are three types of names. First one is ordinary name, second one
is special name, third one is composite name. Special name is a kind
of extended one, it can be connected to us and it can play community
role for others. Only composite names may (and have to) have a '@'
char in them: name1@name2 where name1 is name of some network client
or service and name2 is special name of local service. Local service
may be either some network or directly connected service (IRC bot,
for example). Network services (such as IRC channels) may have also
additional '@' in names and local service name starts after last '@'
then. Any and each local client has an ordinary name, any and each
local service has a special name, clients and services at networks
have composite names, and network clients exist only in runtime but
will never be saved in listfile. Any "service" term below may be
applied to any local or network services.
Client may never have spaces, commas, control chars or colons within
their name. All rest characters are permitted. Case conventions are
locale-dependent.
Interpreters.
------------
Basic interpreter is a config interpreter. No outside scripts can be
run by it. Any other interpreter's interface may be loaded as module
then config command "script" will run appropriate interpreter for
that script file.
Async-unsafe functions.
---------------------
These are functions that cannot be used in threads or interface signal
handlers in part of S_SHUTDOWN.
Signals to interfaces.
--------------------
SS__RREEPPOORRTT:
Generate report and send it to current interface (see the Set_Iface()
API). If it's not I_MODULE then report must be formatted via format
string ReportFormat (see printl() for any details). If it's I_SERVICE
then report for each client that has one of modeflags of ReportMask.
Note that directive %N should be prepended with network specific char
(flag) for the nick and some directives have other meanings in report
format:
%@ - generally "from" name not only host (bot name for example);
%# - connection time string (in format of DateString+TimeString);
%P - socket id (starting from 1, i.e. 0 means there is no socket);
%L - if it's not I_SERVICE or I_CLIENT then interface name;
%* - other descriptive text.
SS__RREEGG:
Reregister all module variables. If interface have to have line in
config file then put that line as request to interface I_INIT with
F_REPORT flag.
SS__FFLLUUSSHH:
Update infos, flush all streams.
SS__SSTTOOPP:
Pause the interface job, usually by setting I_LOCKED interface flag.
Note: if flag I_LOCKED is set on interface then requests for that
interface will be not received at all as if interface does not exist.
SS__CCOONNTTIINNUUEE:
Continue the interface job after stop. (also see note above)
SS__SSHHUUTTDDOOWWNN:
"Quiet" termination of interface. Don't release any memory and/or
other resources, don't call any function but async-safe (see below),
don't lock any mutexes, just close the files and connections. The
message in variable SShhuuttddoowwnnRR may be used as shutdown reason.
SS__TTEERRMMIINNAATTEE:
Terminate the interface. It must stop any job doing by interface and
release every resource that was touched on creating or in process
(i.e. allocated memory, bindings, etc.) except associated data (it
will be released by dispatcher itself). The signal receiver function
must either set interface flag I_DIED or return I_DIED value. The
message in variable SShhuuttddoowwnnRR may be used as termination reason.
SS__WWAAKKEEUUPP:
Main purpose is to use in Add_Timer(), the scheduler will mark the
interface to be ran even if there is no request pending for it (see
Mark_Iface() function description below) when timer expires. It's not
sencible to use it for any other purpose.
SS__TTIIMMEEOOUUTT:
For interface internal usage.
SS__LLOOCCAALL:
For interface internal usage. Will use BindResult for parameters.
Shutdown process.
---------------
Shutdown sequence: all IP connections; all modules; all left interfaces
(if any of them survived). In case of normal shutdown every connection
or module gets signal SS__TTEERRMMIINNAATTEE and all others SS__SSHHUUTTDDOOWWNN. Else every
interface gets signal SS__SSHHUUTTDDOOWWNN. In any case variable SShhuuttddoowwnnRR may
contain reason of shutdown.
Connection chains.
----------------
There is an easy way to extend possibilities of connection by adding
custom filters in the connection flow. Connection chain is chain of
filters. Before you added some filters there is only raw connection
but as soon you called Connchain_Grow() on that peer your connection
is extended. For example, you can add SSL encription or on-the-fly
compression. Each time you call Connchain_Grow() you can insert one
filter on top of chain (on the bottom is raw connection you know) so
when you send data to connection (via Connchain_Put()) they will go
thru the chain from the top to the bottom and when you trying to get
data from connection (via Connchain_Get()) then data will go from
socket thru chain to top of it. There is no way to remove a filter
from the chain because it may destroy all the connection flow so you
have to build your chain carefully (inserting SSL handler as exactly
first link for example). There are two ways to terminate a chain:
- call KillSocket() on the socket; in that case Connchain_Put() will
always return error but you have to call Connchain_Get() to get the
data that may be still left in buffers until it returns error;
- call Connchain_Get() on top of chain with NULL buffer pointer; in
that case connection chain will be destroyed immediately and socket
will be killed too.
Common API:
-----------
Note for reenterability of all APIs:
none means that function is non-reenterable and cannot be called
from threads without locking of dispatcher, in some
cases it may cause even deadlock;
thread-safe means that function can be called from threads;
reenterable means that function can be called recursively;
async-safe means that function can be called even on shutdown.
Threads can call any functions but non-reenterable.
Note: main thread has dispatcher state locked on execution of any of
interface functions so if you want call pthread_join() from there you
must call Unset_Iface() before that and Set_Iface(NULL) after that.
Also remember about deadlock possibility - if you have some mutex in
your code and locked it while in thread then never ever try to call any
function that signed thread-safe or reenterable until you unlock your
mutex.
None of non-reenterable nor async-safe functions is cancellation point.
Also canceling of thread is disabled while dispatcher state is locked
by the thread (see below).
INTERFACE *AAdddd__IIffaaccee (iftype_t _t_y_p_e, const char *_n_a_m_e,
iftype_t (*_s_i_g___f_u_n_c) (INTERFACE *, ifsig_t),
int (*_r_e_q___f_u_n_c) (INTERFACE *, REQUEST *),
void *_d_a_t_a);
Adds interface to dispatcher list. Returns pointer to new created
interface with name _n_a_m_e and flags _t_y_p_e. Interface may have optional
data _d_a_t_a associated with it. Names "@myname" and "*" have special
meanings: interface with _n_a_m_e "@myname" is last resort, i.e. it will
receive requests for "someone@myname" if interface with such name
doesn't exist; interface with _n_a_m_e "*" will receive requests or
signals to any interface of that _t_y_p_e. Each interface must have at
least one of functions _r_e_q___f_u_n_c() for requests or _s_i_g___f_u_n_c() for
signals. These functions may call any API functions since they may
be called only when dispatcher is locked. Interface will be deleted
from dispatcher list after interface flag I_DIED is set, _d_a_t_a will
be deallocated by dispatcher then. Function _r_e_q___f_u_n_c() returns either
REQ_OK if the request was accepted or REQ_REJECTED if it was not.
Function _s_i_g___f_u_n_c() returns additional flags that MUST be set for
interface by caller. Calling this with both _s_i_g___f_u_n_c and _r_e_q___f_u_n_c set
to NULL is undefined behavior and should be used only if you want to
use created interface as clone so you should set field 'prev' in the
interface structure so dispatcher will use it for sending requests
and signals instead. Note: when module terminating then you have to
set interface flag I_DIED for each interface that was added on the
module init. Note2: if you will use this interface as nested one so
will set field 'prev' in the interface structure then you have define
both _s_i_g___f_u_n_c and _r_e_q___f_u_n_c handlers.
Reenterability: reenterable
Cancellation point: no
int RReennaammee__IIffaaccee (INTERFACE *_i_f_a_c_e, const char *_n_e_w_n_a_m_e);
Renames the interface _i_f_a_c_e to new name _n_e_w_n_a_m_e. Changes mask of all
requests queued exactly for it (without destination wildcards) with
new name. Returns 1 on success or 0 if no matched interface found.
Reenterability: reenterable
Cancellation point: no
INTERFACE *SSeett__IIffaaccee (INTERFACE *_i_f_a_c_e);
Sets the interface _i_f_a_c_e as current for Add_Request(), New_Request(),
or Get_Request() call. If _i_f_a_c_e is NULL then it's special case and
current interface will be set to last one was set. Returns previous
pointer to such interface and locks dispatcher state.
Reenterability: thread-safe
Cancellation point: no
INTERFACE *FFiinndd__IIffaaccee (iftype_t _i_f_t, const char *_n_a_m_e);
Finds interface with name _n_a_m_e that has all flags set of mask _i_f_t.
Returns pointer to found interface and locks dispatcher state or
returns NULL if no matched interface found. Note: name search is
case-sensitive so if you want case-insensitive search then do case
conversions yourself when adding interfaces.
Reenterability: reenterable
Cancellation point: no
int UUnnsseett__IIffaaccee (void);
Unlocks dispatcher state that was locked by previous call of function
Set_Iface() or Find_Iface() and restore current interface that was
before that call. Returns 0.
Reenterability: reenterable
Cancellation point: no
void MMaarrkk__IIffaaccee (INTERFACE *_i_f_a_c_e);
Marks interface _i_f_a_c_e to be ran on the next dispatcher cycle even if
there is no requests pending for it and wakes up the dispatcher if it
is sleeping.
Reenterability: none
void AAdddd__RReeqquueesstt (iftype_t _t_y_p_e, const char *_t_o, flag_t _f_l,
const char *_t_e_x_t, _._._.);
Adds request for interfaces matched mask _t_o and flags _t_y_p_e. Request
has mode flags _f_l. Data of request (from _t_e_x_t) is formated string or
interface signal number if _f_l is F_SIGNAL. Request is recoded into
target interface charset when added to queue. See simple_match() for
mask details. Returns nothing.
Reenterability: none if _f_l is F_SIGNAL, else reenterable
Cancellation point: no
void SSeenndd__SSiiggnnaall (iftype_t _t_y_p_e, const char *_t_o, ifsig_t _s_i_g);
Macro, defined as Add_Request(_t_y_p_e, _t_o, F_SIGNAL, (char *)_s_i_g)
Used for sending signals instead of text messages.
Reenterability: none
void NNeeww__RReeqquueesstt (INTERFACE *_i_f_a_c_e, flag_t _f_l, const char *_t_e_x_t, _._._.);
Adds request for interface _i_f_a_c_e. Request has mode flags _f_l. Data of
request (from _t_e_x_t) is formated string or interface signal number if
_f_l is F_SIGNAL. Request is recoded into target interface charset when
added to queue. Returns nothing.
Reenterability: reenterable
Cancellation point: no
int RReellaayy__RReeqquueesstt (iftype_t _i_f_t, char *_n_a_m_e, REQUEST *_r_e_q);
Requeues request _r_e_q for interfaces that are matched mask _n_a_m_e and
flags _i_f_t. See simple_match() for mask details. Always returns value
REQ_OK.
Reenterability: reenterable
Cancellation point: no
int GGeett__RReeqquueesstt (void);
Sends first request to current interface from its queue. Returns
number of requests those was sent and deleted from queue.
Reenterability: reenterable
Cancellation point: no
int AAdddd__HHeellpp (const char *_n_a_m_e);
Adds help file to the help system. If current language isn't "C" and
file _n_a_m_e.$LANG exists then loads that instead of _n_a_m_e. Returns 0 if
file not found, nozero value otherwise.
Reenterability: none
void DDeelleettee__HHeellpp (const char *_n_a_m_e);
Deletes help file _n_a_m_e from the help system. Returns nothing. You
always have to call this function when module terminating for each
help file added on module init.
Reenterability: none
int GGeett__HHeellpp__LL (const char *_f_s_t, const char *_s_e_c, INTERFACE *_i_f_a_c_e,
userflag _g_u_f, userflag _c_u_f, struct bindtable_t *_t_a_b_l_e,
const char *_p_r_e_f_i_x, int _e_a_c_h, int _m_o_d_e,
const char *_l_a_n_g);
Finds help matches first keyword _f_s_t and second keyword _s_e_c that are
in bindtable _t_a_b_l_e and allowed for user with global userflags _g_u_f or
channel userflags _c_u_f, then send help to that topics to interface
_i_f_a_c_e. If _e_a_c_h is 0 then the first line of sent help will begin with
_p_r_e_f_i_x, if _e_a_c_h is 1 then each line will be prefixed. If _m_o_d_e is 0
then sent just usage, if _m_o_d_e is 1 then sent short description and
otherwise full one. Special case 1: if _m_o_d_e is -1 then it works as
if it is 0 but quietly if no help found. Special case 2: if _f_s_t is
NULL but _s_e_c is not then assume first keyword is name of _t_a_b_l_e and
_t_a_b_l_e is extension so check allowance for _s_e_c instead of _f_s_t. In case
if _l_a_n_g is "", returned help is in default language ("C"), otherwise
language _l_a_n_g is searched for help before searching default language.
Note: if _t_a_b_l_e is NULL then assume that allowance is always granted.
Returns number of found topics.
Reenterability: none
int GGeett__HHeellpp (const char *_f_s_t, const char *_s_e_c, INTERFACE *_i_f_a_c_e,
userflag _g_u_f, userflag _c_u_f, struct bindtable_t *_t_a_b_l_e,
const char *_p_r_e_f_i_x, int _m_o_d_e);
Calls Get_Help_L() for language defined in the setting "locale" and
with each=0.
Reenterability: none
void ddpprriinntt (int _l_e_v_e_l, const char *_t_e_x_t, _._._.);
void WWAARRNNIINNGG (const char *_t_e_x_t, _._._.);
void EERRRROORR (const char *_t_e_x_t, _._._.);
Prints debug message _t_e_x_t of given _l_e_v_e_l to all log interfaces. If
_l_e_v_e_l is too high then message is discarded. WARNING() and ERROR()
does the same with debug level 1 and 0 respectively but these levels
does not produces just F_DEBUG messages but F_WARN or F_ERROR too.
Note: it is a side effect, to enable warnings you have to start bot
with debug level at least 1 and if you want to get warnings without
debug then you should use Add_Request() call instead of WARNING().
Reenterability: reenterable
Cancellation point: no
int mmaattcchh (const char *_m_a_s_k, const char *_s_t_r_i_n_g);
Check whether the _s_t_r_i_n_g matches given mask _m_a_s_k. Returns number of
characters (wildcards are not counted) that matched. Cases "*" in
_m_a_s_k or in _s_t_r_i_n_g are special: match() returns 0. The mask is shell
(tcsh, bash, etc.) expansion pattern and may contain:
* matched to any number of any characters
? matched to one any character
[list] matched to any character in list
[^list] matched to any character not in list
(list may contain any number of characters but ']' and
'-' (which may be first ones) and may contain character
ranges, i.e. c-g means cdefg)
{pat1,pat2...} matched to any of patterns pat1, pat2, ...
Aux+Beta matched to literal string "Aux+Beta"
\ quote next char
Note: this function does not perform case-insensitive comparison!
Reenterability: async-safe
int ssiimmppllee__mmaattcchh (const char *_m_a_s_k, const char *_s_t_r_i_n_g);
Check whether the _s_t_r_i_n_g matches given mask _m_a_s_k. Returns number of
characters (wildcards are not counted) that matched. Cases "*" in
_m_a_s_k or in _s_t_r_i_n_g are special: simple_match() returns 0. The mask may
contain:
* matched to any number of any characters
? matched to one any character
\ quote next *, ?, or \ char.
Note: this function does not perform case-insensitive comparison!
Reenterability: async-safe
size_t ssttrrffccppyy (char *_d_s_t, const char *_s_r_c, size_t _n);
Copies null-terminated text string _s_r_c to end of text string in the
_d_s_t but don't exceed maximum string length _n of _d_s_t. In difference of
strncpy() resulted string is always null-terminated. Returns size of
filled _d_s_t (without null char).
Reenterability: async-safe
char *ssttrrffccaatt (char *_d_s_t, const char *_s_r_c, size_t _n);
If _d_s_t is NULL or _n is 0 then returns 0. Else adds null-terminated
text string _s_r_c to end of null-terminated text string in the _d_s_t but
don't exceed maximum string length _n of _d_s_t. Returns _d_s_t.
Reenterability: async-safe
char *ggeettttookkeenn (char *_p_t_r, char **_e_o_w);
Parses null-terminated string _p_t_r, puts a null char at the first word
delimiter in it and if _e_o_w is not NULL then puts pointer to delimiter
into _e_o_w. Returns pointer to next word in the parsed string. If there
are no words left in the string then returns pointer to null char.
Delimiter of words on parsing is space char.
Reenterability: async-safe
char *NNeexxttWWoorrdd (char *_m_s_g);
Finds and returns next space-separated word in the text string _m_s_g.
String _m_s_g is never modified by call.
Reenterability: async-safe
char *NNeexxttWWoorrdd__UUnnqquuootteedd (char *_a_r_g, char *_m_s_g, size_t _s);
If first char in _m_s_g is double quotation mark then extracts all text
up to next quotation mark into array _a_r_g of size _s and skip both
quotation marks. Otherwise puts copy of space-separated word from the
_m_s_g into _a_r_g. Returns pointer to the next word after extracted one.
String _m_s_g is never modified by call.
Reenterability: async-safe
void SSttrrTTrriimm (char *_c_m_d);
Chops all trailing spaces from string _c_m_d. Returns nothing.
Reenterability: async-safe
int HHaavvee__WWiillddccaarrdd (const char *_s_t_r);
Checks null-terminated string _s_t_r for wildcards (see match() function
for details). Returns value 0 or more if there is one, -1 otherwise.
Reenterability: async-safe
size_t pprriinnttll (char *_b_u_f, size_t _s, const char *_t_e_m_p_l, size_t _s_t_r_l_e_n,
char *_n_i_c_k, const char *_u_h_o_s_t, const char *_l_n_a_m_e,
char *_c_h_a_n, uint32_t _i_p, unsigned short _p_o_r_t, int _i_d_l_e,
const char *_m_e_s_s_a_g_e);
Produces output in character array _b_u_f with size _s according to a
format _t_e_m_p_l. Format string is composed of zero or more directives:
ordinary characters (not %), which are copied unchanged to the output
string and conversion specifications. Each conversion specification
is introduced by the % character. Arguments: _n_i_c_k is argument for
%N conversion, _u_h_o_s_t is argument for %@ conversion, _l_n_a_m_e is argument
for %L conversion, _c_h_a_n is argument for %# conversion, _i_p is argument
for %I conversion, _p_o_r_t is argument for %P conversion, _m_e_s_s_a_g_e is
argument for %* conversion, _i_d_l_e is argument for %- conversion. All
other details see in doc/help.format file. Argument _s_t_r_l_e_n is maximum
size of each line (between LFs) in output. Returns size of produced
string (without terminating null char).
Reenterability: none
const char *eexxppaanndd__ppaatthh (char *_b_u_f, const char *_s_t_r, size_t _s);
If path _s_t_r begins from "~/" then substitutes that "~" by value of
environment variable "HOME" in buffer _b_u_f with size _s and returns
pointer to _b_u_f. Otherwise returns _s_t_r.
Reenterability: async-safe
size_t uunniissttrrlloowweerr (char *_d_s_t, const char *_s_r_c, size_t _s_z);
Copies string text from _s_r_c to array in _d_s_t that has size _s_z and
converts copied text to lower case according to current locale.
Returns size of filled _d_s_t (without null char).
Reenterability: async-safe
size_t uunniissttrrccuutt (const char *_l_i_n_e, size_t _l_e_n, int _m_a_x_c_h_a_r_s);
Checks null-terminated string in _l_i_n_e to contain not more than _l_e_n
bytes (including termination byte) and also not more than _m_a_x_c_h_a_r_s
characters (without null char) according to current locale. Returns
size of chunk of string that complies to those conditions in bytes
(without null char) so caller can truncate it. Does not modify _l_i_n_e.
Reenterability: async-safe
void *ssaaffee__ccaalllloocc (size_t _n_m_e_m_b, size_t _s_i_z_e);
void *ssaaffee__mmaalllloocc (size_t _s_i_z_e);
char *ssaaffee__ssttrrdduupp (const char *_s);
Crash-free analogues of standard library functions. Uses the same
syntax but shutdowns the bot instead of SIGSEGV if no memory left
available to allocate. safe_strdup() also returns NULL and does not
allocate memory if tries to duplicate empty string.
Reenterability: thread-safe
Cancellation point: no
void ssaaffee__ffrreeee (void **_p_t_r);
void ssaaffee__rreeaalllloocc (void **_p_t_r, size_t _s);
Crash-free analogues of standard library functions. Shutdowns the
bot instead of SIGSEGV if no memory left available to allocate. In
difference of standard library's free() and realloc() also updates
data in _p_t_r so in case of zero-lenght data it will contain NULL
after return. Returns nothing.
Reenterability: thread-safe
Cancellation point: no
size_t ssaaffee__ssttrrlleenn (const char *_s);
char *ssaaffee__ssttrrcchhrr(char *_s, int _c);
int ssaaffee__ssttrrccmmpp (const char *_s_1, const char *_s_2);
int ssaaffee__ssttrrnnccmmpp (const char *_s_1, const char *_s_2, size_t _n);
int ssaaffee__ssttrrccaasseeccmmpp (const char *_s_1, const char *_s_2);
int ssaaffee__ssttrrnnccaasseeccmmpp (const char *_s_1, const char *_s_2, size_t _n);
Crash-free analogues of standard library functions. Uses the same
syntax but does not produce SIGSEGV in case of NULL arguments.
Reenterability: async-safe
unsigned short make_hash (const char *str);
Reenterability: async-safe
int Merge_Listfile (char *path);
void bboott__sshhuuttddoowwnn (char *_m_e_s_s_a_g_e, int _e);
Does full shutdown. Used mostly in case of critical errors. Returns
never, _m_e_s_s_a_g_e will be used as shutdown reason, _e will be used as
program exit code.
Reenterability: none
Bindings API:
-------------
struct bindtable_t *AAdddd__BBiinnddttaabbllee (const char *_n_a_m_e, bttype_t _t_y_p_e);
Registers bindtable with some _n_a_m_e of some _t_y_p_e. Returns pointer to
structure associated with _n_a_m_e. Subsequent call of Check_Bindtable()
function will check that bindtable. If bindtable with the same name
already exists then returns pointer to it and otherwise pointer to
new created one. If _t_y_p_e is not B_UNDEF and was B_UNDEF on previous
call of Add_Bindtable() then converts bindtable to this _t_y_p_e.
Reenterability: none
struct binding_t *CChheecckk__BBiinnddttaabbllee (struct bindtable_t *_t_a_b_l_e,
const char *_s_t_r, userflag _g_u_f,
userflag _c_u_f, struct binding_t *_l_a_s_t);
Checks bindtable _t_a_b_l_e for entries matched string _s_t_r for users with
matching combination of global userflags _g_u_f and userflags for some
service _c_u_f (see Add_Binding() description for more details). Returns
first matched binding if _l_a_s_t equal NULL. Returns next match if _l_a_s_t
is last found binding and if bindtable type is KEYWORD (see below)
then search will be done by previous literal ignoring _s_t_r. Matched
bindings will be returned in order they were added unless bindtable
type is KEYWORD or UNIQ.
Reenterability: none
const char *BBiinnddttaabbllee__NNaammee (struct bindtable_t *_t_a_b_l_e);
Returns name of already registered bindtable _t_a_b_l_e.
Reenterability: async-safe
struct binding_t *AAdddd__BBiinnddiinngg (const char *_t_a_b_l_e_n_a_m_e, const char *_m_a_s_k,
userflag _g_u_f, userflag _c_u_f,
Function _f_u_n_c, const char *_f_n_a_m_e);
Adds binding to bindtable _t_a_b_l_e_n_a_m_e. Strings checked via bindtable
have to match string _m_a_s_k with current type of mathcing and clients
(or any events that will be checked by Check_Bindtable() afterwards)
must have matched combination of global userflags _g_u_f and selected
service userflags _c_u_f to be available. By default userflags are
matched if client's global flags have all bits set which are set in
_g_u_f or if client's selected service flags have all bits set which are
set in _c_u_f but that behavior can be extended: if any _g_u_f or
_c_u_f have set bit U_NEGATE then userflags will be matched when
appropriate client's flags have no one bit set of those that are set
in binding's ones; and if _c_u_f have set bit U_AND then userflags are
matched if client's global flags have all bits set which are set in
_g_u_f and also client's selected service flags have all bits set which
are set in _c_u_f. Argument _f_u_n_c points to function associated with that
binding. If _f_n_a_m_e is not NULL then _f_u_n_c points to script interpreter
which will get _f_n_a_m_e as first parameter (see below). See match() for
_m_a_s_k details if bindtable is B_MASK or B_UNIQMASK type. Returns
pointer to new added binding. Note: _m_a_s_k must be a lowercase string
until bindtable is B_MATCHCASE type.
Reenterability: none
void DDeelleettee__BBiinnddiinngg (const char *_t_a_b_l_e_n_a_m_e, Function _f_u_n_c,
const char *_f_n_a_m_e);
Deletes bindings that returning _f_u_n_c from bindtable _t_a_b_l_e_n_a_m_e. If
_f_n_a_m_e is NULL then deletes all matched bindings, otherwise deletes
bindings with the same name for script interpreter. Returns nothing.
You always have to call this function when module terminating for
each binding added on module init.
Reenterability: none
int RRuunnBBiinnddiinngg (struct binding_t *_b_i_n_d, const unsigned char *_u_s_e_r,
const char *_f_s_t, const char *_s_e_c, char *_t_h_i_r_d, int _n_u_m,
const char *_l_a_s_t);
Runs script binding defined at _b_i_n_d, with arguments, formed from _u_s_e_r
splitted to nick and user@host, strings _f_s_t, _s_e_c, _t_h_i_r_d, _l_a_s_t, and
integer _n_u_m in order they are in function call. Any NULL values or
empty strings _f_s_t and _s_e_c are ignored, negative _n_u_m too. If value of
_t_h_i_r_d consists of space separated words then it will be splitted to
first word and rest. Returns 0 if binding returned 0 or 1 otherwise.
Any error processing should be done by interpreter module.
Reenterability: none (binding must be since Check_Bindtable)
int LLnnaammee__IIssOOnn (const char *_n_e_t, const char *_p_u_b_l_i_c, const char *_l_n_a_m_e,
const char **_n_a_m_e);
Checks if someone _l_n_a_m_e is currently online for me in the community
_p_u_b_l_i_c on network _n_e_t. Returns 0 if it isn't and not 0 otherwise. If
pointer _n_a_m_e is not NULL then on return it will point to string that
contains last seen nick of this client. If _l_n_a_m_e is NULL then checks
for own nickname on that network service. _p_u_b_l_i_c may be NULL.
Reenterability: none
modeflag IInnssppeecctt__CClliieenntt (const char *_n_e_t, const char *_p_u_b_l_i_c,
const char *_n_a_m_e, const char **_l_n_a_m_e,
const char **_h_o_s_t, time_t *_i_d_l_e, short *_c_n_t);
Checks if someone with nick _n_a_m_e is currently in community _p_u_b_l_i_c on
network _n_e_t. Returns modeflags of _n_a_m_e and if _n_a_m_e is NULL then
returns modeflags the community currently has. If _l_n_a_m_e is not NULL
then on return it will point to string that contains Lname of this
client. If _h_o_s_t is not NULL then on return it will point to string
that contains host string (host or user@host) of this client. If _i_d_l_e
is not NULL then on return it will contain timestamp of last event
for this client. If _c_n_t is not NULL then on return it will contain
service-specific data counter (see also NewEvent() function). If _n_a_m_e
is NULL then _h_o_s_t will point to string that contains community topic.
If _n_a_m_e is hostmask (nick!user@host) then _h_o_s_t will point to string
containing matched mode for the community (for example, ban mask). In
last two cases _l_n_a_m_e will point to string that contains nick of the
client who made that change. If _p_u_b_l_i_c is NULL then checks global
modeflags for the _n_a_m_e (which can be only client name in this case)
in the network.
Reenterability: none
int UUppddaattee__PPuubblliicc (const char *_n_e_t, const char *_p_u_b, modeflag _c_h_a_n_g_e,
const char *_t_g_t, const char *_t_o_p_i_c, const char *_b_y,
time_t _a_t);
Calls a network-specific procedure for community _p_u_b on the network
_n_e_t to update either topic of community, or its mode in accordance
with flags _c_h_a_n_g_e and target _t_g_t. If _c_h_a_n_g_e contains lower bit set to
0 then appropriate flags should be downed on the community, otherwise
flags should be raised. If _t_o_p_i_c is not NULL, then it attempted to be
changed, taking into consideration the values of _b_y (as a person who
changed it) and _a_t (as a time of change), if those parameters can be
supported by a network. Returns 0 if no change was successed, another
value otherwise.
Reenterability: none
Listfile API:
-------------
int AAdddd__CClliieennttrreeccoorrdd (const char *_n_a_m_e, const unsigned char *_m_a_s_k,
userflag _u_f);
Adds user with Lname _n_a_m_e, hostmask _m_a_s_k (in form of nick!user@host
for common users) and global userflags _u_f to Listfile. See match()
description for hostmask details. If _n_a_m_e contains no '.' then _m_a_s_k
will be normalized (i.e. lowercased) on adding. Returns nonull value
if successful.
Reenterability: none
int AAdddd__AAlliiaass (const char *_n_a_m_e, const char *_o_w_n_e_r);
Adds user with Lname _n_a_m_e as alias for user with Lname _o_w_n_e_r to
Listfile. Returns nonull value if successful.
Reenterability: none
void DDeelleettee__CClliieennttrreeccoorrdd (const char *_n_a_m_e);
Deletes user/alias with Lname _n_a_m_e from Listfile. Returns nothing.
Reenterability: none
int CChhaannggee__LLnnaammee (const char *_n_n_e_w, const char *_n_o_l_d);
Changes user Lname _n_o_l_d with new Lname _n_n_e_w in Listfile. Returns 1
if successful, 0 otherwise.
Reenterability: none
userflag ssttrrttoouusseerrffllaagg (const char *_p_t_r, char **_e_n_d_p_t_r);
Converts text string at _p_t_r to userflag. The string may begin with
an arbitrary amount of white space. If _e_n_d_p_t_r is not NULL then the
function stores the address of first invalid character in *_e_n_d_p_t_r.
Reenterability: async-safe
struct clrec_t *FFiinndd__CClliieennttrreeccoorrdd (const unsigned char *_m_a_s_k,
const char **_n_a_m_e, userflag *_u_f,
const char *_n_e_t);
Finds user that is matched to hostmask _m_a_s_k (nick!ident@host]) and
gets his user login _n_a_m_e (Lname below) and his userflags _u_f compiled
from global flags and flags for network _n_e_t (if _n_e_t is NULL then for
direct service). If _m_a_s_k contains wildcards (so apparently it is some
ban or whatever) then finds Listfile record which contains exactly
the same mask. Locks Listfile record of that user. Returns pointer
to internal Listfile record structure. Function never can find any
special user record or alias. Note: Locks in core are complex so
until you want deadlock NEVER use Listfile API calls from above or
any API calls that are marked as thread-safe or reenterable while any
record in Listfile is locked! Note2: this function will scan whole
Listfile database so can be slow sometimes and for the best you have
to use it as few as possible.
Reenterability: thread-safe
Cancellation point: no
struct clrec_t *LLoocckk__CClliieennttrreeccoorrdd (const char *_n_a_m_e);
Locks Listfile record of user with Lname _n_a_m_e. Returns pointer to
internal Listfile record structure or NULL if user was not found.
Note: Locks in core are complex so until you want deadlock NEVER use
Listfile API calls from above or any API calls that are marked as
thread-safe or reenterable while any record in Listfile is locked!
Reenterability: thread-safe
Cancellation point: maybe
struct clrec_t *LLoocckk__bbyyLLIIDD (lid_t _i_d);
Attempts to lock Listfile record of user with LID _i_d. Returns pointer
to internal Listfile record structure or NULL if user was not found.
Note: Locks in core are complex so until you want deadlock NEVER use
Listfile API calls from above or any API calls that are marked as
thread-safe or reenterable while any record in Listfile is locked!
Note2: there is a small chance that there is another record on that
LID already in case if someone deleted record of that LID and created
new one after you've got that _i_d so this method of access to Listfile
record might be considered unreliable.
Reenterability: thread-safe
Cancellation point: maybe
void UUnnlloocckk__CClliieennttrreeccoorrdd (struct clrec_t *_u_s_e_r);
Unlocks Listfile record locked by previous call Find_Clientrecord(),
Lock_Clientrecord(), or Lock_byLID() function. Returns nothing.
Reenterability: thread-safe
Cancellation point: no
char *GGeett__FFiieelldd (struct clrec_t *_u_s_e_r, const char *_f_n, time_t *_t_i_m_e);
Returns content of Listfile field _f_n for user with internal Listfile
record structure at _u_s_e_r. If _f_n is "" then returns current direct
service console settings as string in form "console flags<space>
default service name<space>botnet channel number". If _f_n is NULL
then returns Lname for this record (so if it was alias originally
then returned value will be "host" Lname). If parameter _t_i_m_e is not
NULL then it may get some value: if _f_n is NULL then it gets record
creation time, if _f_n is a special or composite name then it gets
field's expiration time (that is used for bans, for example). Note:
special name must be prepended with '@' to make difference with
custom field names and custom field name should not have '@' nor ':'
within it.
Reenterability: thread-safe
Cancellation point: no
int SSeett__FFiieelldd (struct clrec_t *_u_s_e_r, const char *_f_n, const char *_v_a_l,
time_t _t_i_m_e);
Sets content of Listfile field _f_n for user with internal Listfile
record structure at _u_s_e_r with value _v_a_l. Returns nonull value if
success. If _f_n is "" then sets direct service console settings for
the user. If _t_i_m_e isn't 0 and _f_n is a service name then sets it as
field's expiration time. Note: if _f_n is "alias", Set_Field() will do
not change Listfile (delete old & add new aliases) so you must do it
yourself. Note2: if _f_n is a special name then that name must be
prepended with '@' to make difference with custom field names and
custom field name should not have '@' nor ':' within it. Note3: if _f_n
is one of standard fields ("info" for example) then it cannot contain
any ':' in the _v_a_l.
Reenterability: none
int GGrrooww__FFiieelldd (struct clrec_t *_u_s_e_r, const char *_f_n, const char *_v_a_l);
If Listfile record structure _u_s_e_r has not field _f_n yet then
does the same as previous function. Otherwise adds space and value
_v_a_l to end of string field _f_n. Returns nonull value on success.
Note: if _f_n is "alias", Grow_Field() will do not change Listfile
(delete old & add new aliases) so you must do it yourself. Note2: if
_f_n is a special name then that name must be prepended with '@' to
make difference with custom field names and custom field name should
not have '@' nor ':' within it. Note3: maximum length of resulted
field is limited to 1024 bytes.
Reenterability: none
int AAdddd__MMaasskk (struct clrec_t *_u_s_e_r, const unsigned char *_m_a_s_k);
Adds hostmask _m_a_s_k (usually in form of nick!user@host) for user with
internal Listfile record structure at _u_s_e_r. See match() for hostmask
details. If _u_s_e_r name contains no '.' then _m_a_s_k will be normalized
(i.e. lowercased) on adding. Returns nonull value if successful.
Reenterability: none
int DDeelleettee__MMaasskk (struct clrec_t *_u_s_e_r, const unsigned char *_m_a_s_k);
Deletes all hostmasks matching _m_a_s_k from user with internal Listfile
record structure at _u_s_e_r. See match() for _m_a_s_k details. Returns -1
if no hostmasks left in the record.
Reenterability: none
userflag GGeett__FFllaaggss (struct clrec_t *_u_s_e_r, const char *_s_e_r_v);
Returns userflags of user with internal Listfile record structure at
_u_s_e_r for service _s_e_r_v. If _s_e_r_v is "" then returns direct service
and global userflags. If _s_e_r_v is NULL then returns global userflags.
Reenterability: thread-safe
Cancellation point: no
userflag SSeett__FFllaaggss (struct clrec_t *_u_s_e_r, const char *_s_e_r_v, userflag _u_f);
Attempts to set userflags on internal Listfile record structure at
_u_s_e_r for service _s_e_r_v according to _u_f. If _s_e_r_v is NULL then sets
direct service and global userflags. Take in consideration that some
of flags are immutable and cannot be changed with this function (for
example, you cannot convert normal client record into special one).
Returns userflags that are set now for service _s_e_r_v or 0 in case of
error.
Reenterability: none
lid_t GGeett__LLIIDD (struct clrec_t *_u_s_e_r);
Returns LID for client with internal Listfile record _u_s_e_r. Returned
LID is valid until it deleted from Listfile (you can be notified on
that via bindtable "new-lname").
Reenterability: thread-safe
Cancellation point: no
userflag GGeett__CClliieennttffllaaggss (const char *_n_a_m_e, const char *_s_e_r_v);
Returns userflags of user with Lname _n_a_m_e for service _s_e_r_v. If _s_e_r_v
is "" then returns direct service and global userflags. If _s_e_r_v is
NULL then returns global userflags.
Reenterability: thread-safe
Cancellation point: maybe
int GGeett__CClliieennttlliisstt (INTERFACE *_i_f_a_c_e, userflag _u_f, const char *_f_n,
const char *_m_a_s_k);
Sends list (space separated) of known Lnames which have global
userflags any of _u_f and Listfile field _f_n matched _m_a_s_k, to interface
_i_f_a_c_e via New_Request(). If checked for bans (_u_f contains appropriate
flag) or if _f_n is NULL then Lnames and hostmasks will be checked
against _m_a_s_k. If _f_n is a service name then userflags for that service
will be checked to contain any of _u_f too in case global userflags
were not matched. If found Listfile record is "nonamed" ban then it's
hostmask will be sent instead of missing Lname. Returns number of
requests that were sent. Note: if _f_n is a special name then that name
must be prepended with '@' to make difference with custom field
names.
Reenterability: none
int GGeett__HHoossttlliisstt (INTERFACE *_i_f_a_c_e, lid_t _i_d);
Sends list (space separated) of known hosts for Listfile record with
LID _i_d to interface _i_f_a_c_e via New_Request(). Returns number of
requests that were sent. Note: it's required that you get your _i_d
right away so there will be no chance to get another record on that
LID.
Reenterability: none
int GGeett__FFiieellddlliisstt (INTERFACE *_i_f_a_c_e, lid_t _i_d);
Sends list (space separated) of known fields for Listfile record with
LID _i_d to interface _i_f_a_c_e via New_Request(). Only services (either
special or composite names) or user-defined field names will be sent.
Returns number of requests that were sent. Note: it's required that
you get your _i_d right away so there will be no chance to get another
record on that LID. Note2: special names in reports will be prepended
with '@' to make difference with custom field names.
Reenterability: none
userflag MMaattcchh__CClliieenntt (const char *_h_o_s_t, const char *_i_d_e_n_t,
const char *_n_a_m_e);
Returns OR'ed userflags for all found Listfile records matched to
users with hostmask _i_d_e_n_t@_h_o_s_t and with Lname mask _n_a_m_e.
Reenterability: thread-safe
Cancellation point: no
lid_t FFiinnddLLIIDD (const char *_n_a_m_e);
Returns LID for client with Lname _n_a_m_e. Returned LID is valid until
it deleted from Listfile (you can be notified on that via bindtable
"new-lname").
Reenterability: thread-safe
Cancellation point: maybe
char *uusseerrffllaaggttoossttrr (userflag _f_l_a_g_s, char *_b_u_f_f);
Converts _f_l_a_g_s to string and prints it to buffer _b_u_f_f. Returns _b_u_f_f
pointer. Note: buffer must be long enough to get the string.
Reenterability: async-safe
unsigned short Get_Hosthash (const char *lname, const char *host);
Reenterability: none
Wtmp API:
---------
short EEvveenntt (const char *_e_v_e_n_t);
Returns event number by it name _e_v_e_n_t.
Reenterability: thread-safe
Cancellation point: yes
int FFiinnddEEvveenntt (struct wtmp_t *_t_e_m_p, const char *_u_s_e_r, short _e_v_e_n_t,
lid_t _i_d, time_t _u_p_t_o);
Finds last event for Lname _u_s_e_r and it number _e_v_e_n_t that was logged
from some service _i_d not earlier than _u_p_t_o and writes it to array
_t_e_m_p. Returns -1 if there was an error and 0 otherwise. If _e_v_e_n_t is
W_ANY, the function finds any evend for that _i_d. If _i_d is ID_ME then
finds the event on any service, if _i_d is ID_ANY then finds the event
on any service but direct. If there was no event found then returns
_t_e_m_p zeroed.
Reenterability: thread-safe
Cancellation point: yes
int FFiinnddEEvveennttss (struct wtmp_t *_t_e_m_p, int _w_s, const char *_u_s_e_r,
short _e_v_e_n_t, lid_t _i_d, time_t _u_p_t_o)
Finds not more than _w_s last events for Lname _u_s_e_r and it number _e_v_e_n_t
that was logged from some service _i_d not earlier than _u_p_t_o and writes
it to array _t_e_m_p of size _w_s in order that last event goes into cell
_t_e_m_p[0] and so on. Returns number of found events. If _e_v_e_n_t is W_ANY,
the function finds any evend for that _i_d. If _i_d is ID_ME then finds
the event on any service, if _i_d is ID_ANY then finds the event on any
service but direct.
Reenterability: thread-safe
Cancellation point: yes
void NNeewwEEvveenntt (short _e_v_e_n_t, lid_t _f_r_o_m, lid_t _i_d, short _n_u_m);
void NNeewwEEvveennttss (short _e_v_e_n_t, lid_t _f_r_o_m, size_t _n,
lid_t *_i_d, short *_n_u_m);
Adds one or _n new event record(s) to Wtmp file for client _i_d, its
number _e_v_e_n_t, some service _f_r_o_m with event specific data _n_u_m. For
event W_END on any service that data should be number of client's
activities since corresponding event W_START of that client. Returns
nothing. Note: don't call it with _e_v_e_n_t W_DOWN from threads!
Reenterability: async-safe if _e_v_e_n_t is W_DOWN, else thread-safe
Cancellation point: no
Scheduler-timer API:
--------------------
void NNeewwSShheedduullee (iftype_t _i_f_t, const char *_n_a_m_e, ifsig_t _s_i_g,
char *_m_i_n, char *_h_r, char *_d_s, char *_m_n, char *_w_k);
Sets new schedule mask for some minutes _m_i_n, hours _h_r, days _d_s of
months _m_n on day of week _w_k. Function searches for interface matched
_n_a_m_e and type _i_f_t to schedule the job to it, so it should exist prior
to this function call. See Add_Schedule() function description for
more details.
Reenterability: thread-safe
Cancellation point: no
void AAdddd__SScchheedduullee (INTERFACE *_i_f_a_c_e, ifsig_t _s_i_g, char *_m_i_n, char *_h_r,
char *_d_s, char *_m_n, char *_w_k);
Sets new schedule mask for some minutes _m_i_n, hours _h_r, days _d_s of
months _m_n on day of week _w_k. Each of these submasks is comma
separated list of times: "*[/i]" or "a[-b[/i]]". First format means
do the job each i, second means do each i in interval a to b, that
range is inclusive. If i is omitted then assume it's equal 1, if b
is omitted then assume it's equal to a. Allowed values: _m_i_n 0-59,
_h_r 0-23, _d_s 1-31, _m_n 1-12, _w_k 0-7, since real time will never reach
other. When schedule is matched then signal _s_i_g will be sent to the
interface _i_f_a_c_e. Returns nothing.
Reenterability: none
void KKiillllSShheedduullee (iftype_t _i_f_t, const char *_n_a_m_e, ifsig_t _s_i_g,
char *_m_i_n, char *_h_r, char *_d_s, char *_m_n, char *_w_k);
Aborts schedule mask. Synopsis is equal to NewShedule().
Reenterability: thread-safe
Cancellation point: no
void SSttoopp__SScchheedduullee (INTERFACE *_i_f_a_c_e, ifsig_t _s_i_g, char *_m_i_n, char *_h_r,
char *_d_s, char *_m_n, char *_w_k);
Aborts schedule mask. Synopsis is equal to Add_Schedule().
Reenterability: none
tid_t NNeewwTTiimmeerr (iftype_t _i_f_t, const char *_n_a_m_e, ifsig_t _s_i_g,
unsigned int _s_e_c, unsigned int _m_i_n, unsigned int _h_r,
unsigned int _d_s);
Set new schedule job for _s_e_c seconds, _m_i_n minutes, _h_r hours and _d_s
days since current time. Function searches for interface matched _n_a_m_e
and type _i_f_t to schedule the job to it, so it should exist prior to
this function call. See Add_Timer() function description for more
details.
Reenterability: thread-safe
Cancellation point: no
tid_t AAdddd__TTiimmeerr (INTERFACE *_i_f_a_c_e, ifsig_t _s_i_g, time_t _s_e_c);
Set new schedule job for _s_e_c seconds since current time. When the job
time is reached then signal _s_i_g will be sent to the interface _i_f_a_c_e.
Returns new schedule job identifier if schedule set successful or -1
otherwise. Note: if a job was previously set on the same second for
the same interface with the same signal then function will return an
identifier assigned before and don't assing duplicate job to it.
Reenterability: none
void KKiillllTTiimmeerr (tid_t _t_i_d);
Aborts schedule job with identifier _t_i_d. Returns nothing.
Reenterability: thread-safe
Cancellation point: no
int CChheecckkFFlloooodd (short *_c_o_u_n_t_e_r, short _f_l_o_o_d_t_y_p_e[2]);
Sets new flood entry. Value of _c_o_u_n_t_e_r checked for max value from
_f_l_o_o_d_t_y_p_e[0]. Counter will be decremented after _f_l_o_o_d_t_y_p_e[1] seconds
since call. Returns >0 if flood was detected.
Reenterability: none
void NNooCChheecckkFFlloooodd (short *_c_o_u_n_t_e_r);
Aborts all flood entries for given _c_o_u_n_t_e_r. Returns nothing.
Reenterability: none
Scripts API:
------------
char *BBiinnddRReessuulltt;
Contains string result of last executed binding.
Reenterability: none
time_t SSttaarrttTTiimmee;
Contains time when client core was started.
Reenterability: none
char *DDaatteeSSttrriinngg;
Contains current date in the form "%e %b" (see man strftime).
Reenterability: none
char *TTiimmeeSSttrriinngg;
Contains current time in the form "%H:%M" (see man strftime).
Reenterability: none
time_t TTiimmee;
Contains current local UNIX time.
Reenterability: none
int RReeggiisstteerrFFuunnccttiioonn (const char *_c_m_d, int (*_f_u_n_c)(const char *),
const char *_m_s_g);
Registers the function _f_u_n_c() in all interpreters with name _c_m_d.
Optional message _m_s_g may be used in prompt by config generator.
Returns 1 if function was registered.
Function _f_u_n_c() gets string arguments (may be with ending spaces)
and returns 0 on error or any other value otherwise. Return value is
dependent on called function. In case of error BindResult may contain
some error message or may be left untouched. Since the function can
be used in config file it must allow duplicate calls, possibly with
updated arguments.
Reenterability: none
int UUnnrreeggiisstteerrFFuunnccttiioonn (const char *_c_m_d);
Deletes function with name _c_m_d from all interpreters. Returns 1 if
function was deleted. You always have to call this function when
module terminating for each command that was added on module init.
Reenterability: none
int RReeggiisstteerrBBoooolleeaann (const char *_b_o_o_l, bool *_v_a_r);
Registers boolean variable _v_a_r in all interpreters with name _b_o_o_l.
Returns 1 if variable was registered.
Reenterability: none
int RReeggiisstteerrIInntteeggeerr (const char *_i_n_t, long int *_v_a_r);
Registers integer variable _v_a_r in all interpreters with name _i_n_t.
Returns 1 if variable was registered.
Reenterability: none
int RReeggiisstteerrSSttrriinngg (const char *_s_t_r, char *_p_t_r, size_t _c_o_u_n_t, int _r_o);
Registers string variable at address _p_t_r with size of _c_o_u_n_t bytes in
all interpreters with name _s_t_r. If _r_o is not 0, attempt of change
that variable will cause script interpreter error. Returns 1 if
variable was registered.
Reenterability: none
int UUnnrreeggiisstteerrVVaarriiaabbllee (const char *_v_a_r);
Deletes any variable with name _v_a_r from all interpreters. Returns 1
if variable was deleted. You always have to call this function when
module terminating for each variable that was added on module init.
Reenterability: none
int GGeettVVaarriiaabbllee (const char *_n_a_m_e, VariableType _t_y_p_e, void **_p_t_r);
Finds already registered variable by its _n_a_m_e and _t_y_p_e. Returns 1 if
variable found and returns pointer to it in _p_t_r. Returns 0 otherwise.
Access to the variable assumed to be read-only, main purpose of this
function is to test data of one module from another one at the init
stage.
Reenterability: none
short *FFllooooddTTyyppee (const char *_n_a_m_e);
Creates new or finds existing flood structure associated with given
_n_a_m_e. Returns pointer to flood pair (see CheckFlood() function).
Reenterability: none
char *SSeettFFoorrmmaatt (const char *_n_a_m_e, char *_v_a_l);
Creates new or finds existing format string with max size FORMATMAX
that associated with given _n_a_m_e, and updates it with _v_a_l. Returns
pointer to that string.
Reenterability: none
int SSaavvee__FFoorrmmaattss (void);
Saves all formats into file with path (char *)FormatsFile as strings
"name value", overwriting file if exist. Returns 0 on success.
Reenterability: none
int CCoonnffiigg__EExxeecc (const char *_c_m_d, const char *_a_r_g_s);
Runs function that was registered via RegisterFunction(). Function
_c_m_d will get one argument - text string _a_r_g_s. Returns value that was
returned by _c_m_d(_a_r_g_s). Note: this function can also run few built-in
config file commands ("set", "script", and "flood-type") so this is
the only way to run them not from config file.
Reenterability: none
bool CCoonnffiirrmm (char *_m_e_s_s_a_g_e, bool _d_e_f_l);
Waits until user (via module "ui") confirm (i.e. enters "y" or "n")
and then returns TRUE or FALSE. User will get prompt composed from
_m_e_s_s_a_g_e and default value from _d_e_f_l. Returns immediately if that
variable _d_e_f_l doesn't need to be asked (has no flag ASK) or if "ui"
module doesn't exist. In that case returns TRUE or FALSE from _d_e_f_l.
Note: don't lock dispatcher before Confirm() or you'll get freeze
or even deadlock!
Reenterability: may be called only from threads
Cancellation point: yes
Sockets API:
------------
idx_t GGeettSSoocckkeett (unsigned short _m_o_d_e);
Creates new socket. Socket must be sets up by SetupSocket() later and
it will have requested _m_o_d_e. Returns new socket identifier or -1 if
failed. Note: that socket must be owned by thread that called this
GetSocket() and closed only by it.
Reenterability: thread-safe
Cancellation point: no (?)
int SSeettuuppSSoocckkeett (idx_t _i_d_x, const char *_d_o_m_a_i_n, const char *_b_i_n_d___t_o,
unsigned short _p_o_r_t,
int (*_c_a_l_l_b_a_c_k)(const struct sockaddr *_s_a, void *_c_b_d),
void *_c_b_d);
Sets up new socket in non-block mode, establishes connection to port
_p_o_r_t of Internet address with name _d_o_m_a_i_n from local Internet address
with name _b_i_n_d___t_o if socket was created with mode M_RAW or opens new
listening socket on Internet address with name _b_i_n_d___t_o if socket was
created with mode M_LIST, M_LINP, or M_UNIX (parameter _d_o_m_a_i_n will be
ignored in that case). If socket was created as M_LINP then listening
socket will be opened only for single connection. Parameter _p_o_r_t is
ignored when listening Unix socket (i.e. socket mode is M_UNIX). If
parameter _b_i_n_d___t_o is NULL then default will be used if it's possible.
Returns 0 on success or error code otherwise. If _c_a_l_l_b_a_c_k is not NULL
then function _c_a_l_l_b_a_c_k will be called with address _s_a and callback
data _c_b_d as last step of the socket setup.
Reenterability: thread-safe
Cancellation point: yes
idx_t AAnnsswweerrSSoocckkeett (idx_t _i_d_x);
Attempts to answer for listening socket _i_d_x. Returns new socket
identifier or -1 if no connections was made. Note: never cancel the
thread where there is this call or you may get deadlock.
Reenterability: thread-safe
Cancellation point: yes
int KKiillllSSoocckkeett (idx_t *_i_d_x);
Closes the socket with identifier _i_d_x. Returns 0 if socket closed
OK, -1 otherwise. Note: this function must be called by and only
by thread that opened the socket before.
Reenterability: thread-safe
Cancellation point: maybe
const char *SSoocckkeettDDoommaaiinn (idx_t _i_d_x, unsigned short *_p);
Returns domain name for socket _i_d_x. If _p is not NULL then also puts
port of the socket in *_p. If socket is opened in listen mode then
returns own domain and port. If socket is answered to M_UNIX listener
then function may return PID of process that connected to it (it text
form) and UID of that process owner in *_p. If no matched socket found
then _p will be left untouched and function returns empty string
but no NULL.
Reenterability: async-safe
const char *SSoocckkeettIIPP (idx_t _i_d_x);
Returns textual representation (name) for IP of socket _i_d_x. If socket
is opened in listen mode then returns listening IP name. If there is
no such socket then returns empty string but no NULL.
Reenterability: async-safe
const char *SSoocckkeettMMyyIIPP (idx_t _i_d_x, char *_b_u_f, size_t _b_s_z);
Makes textual representation (own name) for IP of socket _i_d_x which we
accepted connection on. Name will be reconstructed in buffer _b_u_f of
size _b_s_z. Returns value of _b_u_f or NULL in case of error.
char *SSoocckkeettEErrrroorr (int _e_r_r, char *_b_u_f, size_t _s_z);
Returns text in buffer _b_u_f of size _s_z that describing error code _e_r_r
that was returned by function SetupSocket() or ReadSocket(). Returns
value of _b_u_f.
Reenterability: async-safe
ssize_t RReeaaddSSoocckkeett (char *_b_u_f, idx_t _i_d_x, size_t _s_z);
Reads raw data from socket _i_d_x to buffer _b_u_f of max size _s_z and then
returns size of read data. If there was an error on the socket then
returns error code and if socket was died unexpectedly then returns
E_NOSOCKET.
Also may return E_AGAIN if socket is waiting for a connection.
Reenterability: thread-safe
Cancellation point: maybe
ssize_t WWrriitteeSSoocckkeett (idx_t _i_d_x, const char *_b_u_f, size_t *_p_t_r,
size_t *_s_z);
Writes raw data of size _s_z to socket _i_d_x from buffer _b_u_f at _p_t_r.
Returns number of bytes written and changes counters _p_t_r and _s_z. If
there was an error on socket then returns error code and if socket
was died unexpectedly then returns E_NOSOCKET.
Reenterability: thread-safe
Cancellation point: maybe
void AAssssoocciiaatteeSSoocckkeett (idx_t _i_d_x, void (*_c_a_l_l_b_a_c_k)(void *_c_a_l_l_b_a_c_k___d_a_t_a),
void *_c_a_l_l_b_a_c_k___d_a_t_a);
Adds a hook onto valid socket _i_d_x. When socket state is changed (so
either new data came, connection closed, etc.) the _c_a_l_l_b_a_c_k will be
called with a parameter _c_a_l_l_b_a_c_k___d_a_t_a. At the moment of call sockets
are locked therefore callback should be async-safe or otherwise it is
possible to get a deadlock. Note on reenterability: the function does
not change any other data so should be safe to call from a thread if
that thread ensures the socket is owned by a calling thread.
Reenterability: none
Direct client's connections API:
--------------------------------
void DDcccc__PPaarrssee (struct peer_t *_s, char *_n_a_m_e, char *_c_m_d, userflag _g_f,
userflag _c_f, int _i_d_x, int _b_o_t_c_h,
struct bindtable_t *_s_s_b_t, char *_s_e_r_v_i_c_e);
Parses text line _c_m_d that came from session _s. If first char of _c_m_d
is not period ('.') then sends text line to botnet channel _b_o_t_c_h.
Else if there is service specific bindtable _s_s_b_t (for _s_e_r_v_i_c_e) then
checks first word of the line for available command in it. If no
such bindtable or command is not found in it then checks first word
of the line in bindtable "dcc". If there is appropriate command then
runs function for it or else sends usage tip into _s. Does logging if
command was successful. Login _n_a_m_e, direct access flags _g_f, service
access flags _c_f, and socket ID _i_d_x are for client of the session _s.
This function can be used for any valid peer but it's not advisable
to use it for anything but direct session because bindings or usage
tip may break interface protocol otherwise. Returns nothing.
Reenterability: none
int LLiisstteenn__PPoorrtt (char *_c_l_n, const char *_l_h_o_s_t, unsigned short _p,
char *_c_o_n_f_l_i_n_e, void *_i_d,
int (*_l_c_b) (const struct sockaddr *_s_a, void *_i_d),
void (*_p_r_e_h_a_n_d_l_e_r) (pthread_t _t_h, void **_i_d, idx_t *_a_s),
void (*_h_a_n_d_l_e_r) (char *_c_l_n, char *_i_d_e_n_t,
const char *_r_h_o_s_t, void *_i_d));
Opens listener for client name _c_l_n on port _p. _l_h_o_s_t is host name on
which listener will be opened (if it is NULL then listener will be
opened on all local IPs). If _p is 0 then tries ports accordingly to
variable "dcc-port-range". It creates thread where opens a listening
socket and when connection is accepted then creates new thread where
gets ident (see RFC1413) for incoming connection and then passes data
of new connection (client name _c_l_n and value _i_d from caller, and
_i_d_e_n_t and _r_h_o_s_t from input connection) to function _h_a_n_d_l_e_r (in that
accepting thread). Returns 0 if the listening thread was created
succesfully or returns error code otherwise. If callback function _l_c_b
is not NULL then it will be called from the listening thread after
finishing of socket setup. In case of any errors _l_c_b will be called
with _s_a equal to NULL. In case of success _l_c_b still can return some
error code to raise the error. In both cases _l_c_b should inform caller
thread to take care of data _i_d. In any case those data will be freed
by listening thread so should never be freed or accessed from ouside
of the listening thread (also note: to prevent memory leak those data
should not contain any allocated data). The callback _l_c_b should be
thread-safe and may return E_AGAIN to make a retry. If _c_o_n_f_l_i_n_e is
not NULL then this port will be reported to config as _c_o_n_f_l_i_n_e. The
listening thread interface created in dispatcher with name _c_o_n_f_l_i_n_e
(or with name consisting of opened port number if _c_o_n_f_l_i_n_e is NULL)
and with type I_LISTEN. If _c_l_n is not NULL then listening socket will
be closed as soon as connection was accepted. If _p_r_e_h_a_n_d_l_e_r is not
NULL then it will be called from the listening thread each time when
connection is accepted with new thread identifier _t_h, pointer to _i_d,
and the accepted socket ID _a_s so caller may cancel that thread on
emergency. Canceling of the listening thread is disabled while the
_p_r_e_h_a_n_d_l_e_r is called. Data in _i_d are owned by the created interface
on call of _p_r_e_h_a_n_d_l_e_r so that function should make a local copy if
the accepting thread requires it or replace it with NULL otherwise.
The _p_r_e_h_a_n_d_l_e_r should remember _a_s in optionally created data _i_d and
if pointer in _i_d is NULL after call to _p_r_e_h_a_n_d_l_e_r then _h_a_n_d_l_e_r will
be called with _i_d that points to _a_s instead so _h_a_n_d_l_e_r can know it in
any case. In case if any error happened in the listening thread then
_p_r_e_h_a_n_d_l_e_r will be called with _a_s equal to -1 and undefined _t_h to
notify caller about that. Since that might be also as result of
thread cancellation, _p_r_e_h_a_n_d_l_e_r should not call any but async-safe
functions in that case. Accepting thread will wait for data returned
by _p_r_e_h_a_n_d_l_e_r before calling the _h_a_n_d_l_e_r and pass that data to it.
Socket of accepted connection is owned by the listening thread and
inherited by the accepting thread (so function _h_a_n_d_l_e_r at the end).
Note: if _p is 0 then _l_c_b is the only way to let caller know which
port is listening in real.
Reenterability: none
int CCoonnnneecctt__HHoosstt (const char *_h_o_s_t, unsigned short _p_o_r_t, pthread_t *_t_h,
idx_t *_s_o_c_k_e_t, void (*_h_a_n_d_l_e_r) (int _r_e_s, void *_i_d),
void *_i_d);
Attempts to create a thread to open outgoing connection to some _h_o_s_t
on some _p_o_r_t. It does DNS lookup then opens connection. After that
(eighter success or failure) given _h_a_n_d_l_e_r will be called with two
parameters: error code _r_e_s and value _i_d from caller. The thread is
joinable and caller gets identifiers _t_h of the thread and _s_o_c_k_e_t of
the socket which is waiting for connection at that moment. Socket is
owned by created thread. Returns 1 if there was no errors and thread
is created or 0 otherwise.
Reenterability: async-safe
int CChheecckk__PPaasssswwdd (const char *_p_l_a_i_n, char *_e_n_c_r);
Checks if _p_l_a_i_n text password has the same encrypted value as _e_n_c_r.
Returns 0 if password matches.
Reenterability: none
int PPeeeerrDDaattaa__AAttttaacchh (struct peer_t *_s, const char *_n_a_m_e, void *_d_a_t_a,
void (*_d_e_s_t_r_o_y)(void *));
Attempts to attach _d_a_t_a to the peer _s with key _n_a_m_e which should be
an unique identifier such as module name and be some constant value.
Caller should provide _d_e_s_t_r_o_y function which is called on next call
PeerData_Detach() or Peer_Cleanup(). If data are allocated and not
bound to some controlled storage then providing _d_e_s_t_r_o_y function is
mandatory to avoid memory leak. Returns 1 on success, 0 on failure.
Reenterability: none
void PPeeeerrDDaattaa__DDeettaacchh (struct peer_t *_s, const char *_n_a_m_e);
Removes any data from peer _s which are associated with _n_a_m_e. If some
cleanup function was provided to PeerData_Attach() then it will be
called on found data.
Reenterability: none
void *PPeeeerrDDaattaa__GGeett (struct peer_t *_s, const char *_n_a_m_e);
Retrieves data previously associated with peer _s using key _n_a_m_e. If
no data found then returns NULL.
Reenterability: none
void PPeeeerr__CClleeaannuupp (struct peer_t *_s);
Destroys connection chain (see below), kills socket (see KillSocket()
for details) and frees any associated data (see PeerData_Attach() for
details) on peer _s.
Reenterability: none
Connection chain API:
---------------------
int CCoonnnncchhaaiinn__GGrrooww (struct peer_t *_p_e_e_r, char _f);
Adds filter of type _f at top of connection chain of _p_e_e_r. Returns 1
if filter was added, 0 if filter not found, and -1 in case of error
(which may be in case of dead connection or in case when there is
some filter with the same handlers in the chain already so that may
be considered as duplicate filter try). You should always call this
at least once before you can use any of functions Connchain_Put(),
Connchain_Get(), Connchain_Kill(), Peer_Put(), or Peer_Get(). You
must always call Connchain_Kill() for any peer where you created
connection chain with Connchain_Grow(). Note: adding filters 'x' or
'y' that are implemented in core will never return 0. Note2: there is
a completely legal way to reset all connection chain by binding which
setups that new filter so be careful. Note3: on very first filter add
this function will add a hook on the socket to wake up the associated
interface so both should already exist at that moment, and interface
should be never freed or replaced until socket is killed.
* Filter 'x' : on send adds CR+LF to end of line, accepts line with
at most MB_LEN_MAX*MESSAGEMAX-1 chars including terminating null
byte; on receive accepts raw stream, selects lines that are ended
with LF or CR+LF and returns them one by one, replacing LF or CR+LF
with null byte (that byte counts in return).
* Filter 'y' : on send replaces each 0xFF byte with two 0xFF+0xFF as
stated in RFC854; on receive does backward conversion into 0xFF,
ignores any ECHO commands, answers "Y" on AYT, DON'T on WILL, WON'T
on DO, and skips other RFC854 codes.
Reenterability: none
int CCoonnnncchhaaiinn__CChheecckk (struct peer_t *_p_e_e_r, char _f);
Performs any checks that Connchain_Grow() does but does not actually
add a filter into connection chain.
Reenterability: none
int CCoonnnncchhaaiinn__SShhrriinnkk (struct peer_t *_p_e_e_r, struct connchain_i *_c_h_a_i_n);
Removes current connchain filter from the _p_e_e_r's connection chain.
This function may be called only from recv() callback of the filter
and it should get parameter _c_h_a_i_n passed to the callback. The filter
and its data will be released after this call therefore it should be
the last call before return from the callback if filter wanted to do
such suicide. Returns 1 in case of success.
Reenterability: none
ssize_t CCoonnnncchhaaiinn__PPuutt (struct connchain_i **_c_c, idx_t _i_d_x, const char *_l_i_n_e,
size_t *_s);
Tries to filter and send data of size _s from buffer _l_i_n_e through next
link of connection chain _c_c for socket identifier _i_d_x. If _l_i_n_e is
NULL then it tries to send what is still left in chain's own buffers
and in that case either returns error (if nothing left to send into
socket _i_d_x) or number of bytes sent (i.e. 0). If _l_i_n_e isn't NULL but
_s contains 0 then it returns value CONNCHAIN_READY in case when chain
can take data for sending on next call or some other value otherwise.
If there are data to send and there were no errors encountered then
appropriately updates counter at _s and returns number of bytes that
were sent. It will use N_POLL socket writing mode if peer state is
P_DISCONNECTED or P_INITIAL. This function should never close or
destroy the socket.
Reenterability: async-safe
ssize_t CCoonnnncchhaaiinn__GGeett (struct connchain_i **_c_c, idx_t _i_d_x, char *_b_u_f,
size_t _s);
Tries to receive and filter data from socket _i_d_x through connection
chain _c_c and put them into buffer _b_u_f of maximum size _s. If _b_u_f is
NULL then chain will be destroyed immediately. If there was an error
on receiving data then chain will return data that still left in
buffers and if no data left then chain will be destroyed. If socket
is still waiting for connection then it counts as error too. This
function should never close or destroy the socket. In case if _i_d_x is
-1 then chain will return raw unprocessed data if there is something
left in buffers and if no data left then return error. Returns either
error code or size of data that was received into _b_u_f.
Reenterability: thread-safe
Cancellation point: maybe
CCoonnnncchhaaiinn__KKiillll (struct peer_t *_p_e_e_r);
Macro, defined as: Connchain_Get(&_p_e_e_r->connchain,_p_e_e_r->socket,NULL,0)
Used for terminating connection chain. Returns value E_NOSOCKET but
generates warning if that value left unused. Note that you probably
should never use this function directly but Peer_Cleanup() instead as
other modules might attach data to your _p_e_e_r and latter function will
do all required cleanup on your connection chain.
Reenterability: thread-safe
Cancellation point: maybe
PPeeeerr__PPuutt (struct peer_t *_p_e_e_r, const char *_b_u_f, size_t *_s);
Macro, defined as: Connchain_Put(&_p_e_e_r->connchain,_p_e_e_r->socket,_b_u_f,_s)
Used for putting data on the top of connection chain.
Reenterability: thread-safe
Cancellation point: maybe
PPeeeerr__GGeett (struct peer_t *_p_e_e_r, char *_b_u_f, size_t _s);
Macro, defined as: Connchain_Get(&_p_e_e_r->connchain,_p_e_e_r->socket,_b_u_f,_s)
Used for the getting data from the top of connection chain.
Reenterability: thread-safe
Cancellation point: maybe
Charset conversions API:
------------------------
struct conversion_t *GGeett__CCoonnvveerrssiioonn (const char *_c_s);
Allocates and returns conversion descriptor for charset name _c_s. If
_c_s is not valid charset name then returns NULL. If _c_s is internal
charset then returns NULL too.
Reenterability: thread-safe
Cancellation point: no
void FFrreeee__CCoonnvveerrssiioonn (struct conversion_t *_c_o_n_v);
Releases conversion descriptor _c_o_n_v. Returns nothing.
Reenterability: thread-safe
Cancellation point: no
struct conversion_t *CClloonnee__CCoonnvveerrssiioonn (struct conversion_t *_c_o_n_v);
Allocates and returns conversion descriptor that is equal to _c_o_n_v.
Reenterability: thread-safe
Cancellation point: no
const char *CCoonnvveerrssiioonn__CChhaarrsseett (struct conversion_t *_c_o_n_v);
Returns charset name for conversion descriptor _c_o_n_v.
Reenterability: thread-safe
Cancellation point: no
size_t DDoo__CCoonnvveerrssiioonn (struct conversion_t *_c_o_n_v, char **_o_u_t,
size_t _o_u_t_s_z, const char *_i_n, size_t *_i_n_s_z);
Does conversion of text line _i_n of size _i_n_s_z from charset defined by
conversion descriptor _c_o_n_v to internal charset. Puts converted text
into buffer _o_u_t of size _o_u_t_s_z. If there is no conversion need then
on return variable by _o_u_t will contain value of _i_n. Returns size of
converted line and changes _i_n_s_z to size of data that still left
unconverted.
Reenterability: thread-safe
Cancellation point: no
size_t UUnnddoo__CCoonnvveerrssiioonn (struct conversion_t *_c_o_n_v, char **_o_u_t,
size_t _o_u_t_s_z, const char *_i_n, size_t *_i_n_s_z);
Does conversion of text line _i_n of size _i_n_s_z from internal charset
to charset defined by conversion descriptor _c_o_n_v. Puts converted
text into buffer _o_u_t of size _o_u_t_s_z. If there is no conversion need
then on return variable by _o_u_t will contain value of _i_n. Returns
size of converted line and changes _i_n_s_z to size of data that still
left unconverted.
Reenterability: thread-safe
Cancellation point: no
Calling of bindings:
--------------------
Flags:
KEYWORD matching of keyword (followed by space) to literal
MASK matching of string to mask
MATCHCASE case-sensitive matching of keyword to mask
UNIQ unique (replacing) binding for matching of keyword to literal
UCOMPL the same with completion
UNIQMASK unique (replacing) binding for matching of string to mask
All int func() returns 0 if binding did not executed. If binding executed
but result should be ignored (no logs for example) then func() may return
value -1. All bindings may be non-reenterable if another wasn't declared.
Every matched binding in non-unique bindtable type should be called on
bindtable check if another wasn't declared.
Interpreter entrance for bindings:
int func(char *_f_n_a_m_e, int _a_r_g_c, const char *_a_r_g_v[]);
Call interpreter function _f_n_a_m_e with _a_r_g_c arguments array _a_r_g_v (see
the "Script args:" label below and if there is no such label on the
bindtable then interpreter bindings will be never called even if some
of them exist). If _f_n_a_m_e is "-" then interpreter should return its
name. If binding returns text then that text should go into variable
BindResult. In case of error it should put message describing error
into log. Note: _a_r_g_c value can be from 0 to 8.
Builted in bindings: since C does not have possibility to have typedef for
function, only way to have type control is to insert line composited from
'BINDING_TYPE_' with bindtable name with dashes replaced by underscores
and function name before binding's definition, for example:
BINDING_TYPE_add_ui (au_test); /* for bindtable "add-ui" */
static int au_test (INTERFACE *iface, char *s)
.......
Since we want to avoid crashes, using this line is mandatory for every
binding we create. Note: use BINDING_TYPE_ss_ for ss-* bindtables.
Core bindtables:
----------------
DCC "ddcccc" UCOMPL
int func(struct peer_t *_f_r_o_m, char *_a_r_g_s);
Used when user enters the command on partyline. Partyline member
identified with session _f_r_o_m. Arguments _a_r_g_s to command are stripped
from leading spaces and if no arguments were found then _a_r_g_s is NULL.
Note: matching global+direct service flags instead of just global and
service is from console settings.
Matching: first word of partyline command without leading '.'.
Script args: Lname Dcc-idx args
- "ssss--**" UCOMPL
int func(struct peer_t *_w_h_o, INTERFACE *_w_h_e_r_e, char *_a_r_g_s);
Used when user _w_h_o enters server-specific command on user interface.
Other side (I_SERVICE or I_CLIENT) is specified by _w_h_e_r_e. Arguments
_a_r_g_s to command are stripped from leading spaces. "**" in the name
means network type (i.e. "irc", etc.). That's similar to and is
extension of "ddcccc" bindtable.
Matching: first word of command without leading '.'.
CHAT "cchhaatt" MASK
(int) void func(struct peer_t *_f_r_o_m, char *_m_s_g);
Used when somebody says anything (text _m_s_g) on the partyline/botnet.
Partyline member identified with session _f_r_o_m.
Matching: full text line.
Script args: Lname BotChannel msg
ACT "cchhaatt-aacctt" MASK
(int) void func(struct peer_t *_f_r_o_m, char *_m_s_g);
Used when somebody does an action (text _m_s_g) on the partyline/botnet.
Partyline member identified with session _f_r_o_m.
Matching: full text line. (any channel userflags are ignored)
Script args: Lname BotChannel msg
FILT "iinn--ffiilltteerr" MASK
(int) void func(struct peer_t *_f_r_o_m, char *_m_s_g, size_t _m_s_g_l_e_n);
Used for filtering text _m_s_g on the partyline before parsing. All
filters matched user (identified by _f_r_o_m) flags and text mask will
be applied. Null-terminated text at area _m_s_g no longer than _m_s_g_l_e_n
can be rewritten by internal binding.
Matching: full text line. (any channel userflags are ignored)
Matching stops when text is empty.
Script args: Dcc-idx msg
Bind result: new text line.
- "oouutt--ffiilltteerr" MASK
(int) void func(struct peer_t *_t_o, char *_m_s_g, size_t _m_s_g_l_e_n);
Used for filtering text _m_s_g before sending to partyline user. All
filters matched user (identified by _t_o) flags and text mask will be
applied. Null-terminated text at area _m_s_g no longer than _m_s_g_l_e_n can
be rewritten.
Matching: full text line. (any channel userflags are ignored)
Matching stops when text is empty.
Script args: Dcc-idx msg
Bind result: new text line.
CHON "cchhaatt--oonn" MASK
(int) void func(struct peer_t *_w_h_o);
Used when somebody _w_h_o enters a DCC CHAT partyline.
Matching: Lname.
Script args: Lname Dcc-idx
CHOF "cchhaatt--ooffff" MASK
(int) void func(struct peer_t *_w_h_o);
Used when somebody _w_h_o "logoff" from DCC CHAT partyline.
Matching: Lname.
Script args: Lname Dcc-idx
CHJN "cchhaatt--jjooiinn" MASK
(int) void func(INTERFACE *_i_f_a_c_e, int _b_c_h_a_n, const char *_h_o_s_t);
Used when somebody _i_f_a_c_e (coming from _h_o_s_t) joins a botnet channel
_b_c_h_a_n.
Matching: bchan. (userflags are ignored)
Script args: botname uname bchan dccuserchar Dcc-idx host
CHPT "cchhaatt--ppaarrtt" MASK
(int) void func(INTERFACE *_i_f_a_c_e, int _b_c_h_a_n);
Used when somebody _i_f_a_c_e parts a botnet channel _b_c_h_a_n.
Matching: bchan. (userflags are ignored)
Script args: botname uname Dcc-idx bchan
- "ppaasssswwdd" UNIQMASK
(int) void func(const char *_p_a_s_s, char **_c_r_y_p_t_e_d);
Used for translation plain-text _p_a_s_s password to encripted form
pointed by _c_r_y_p_t_e_d. If previous value of _c_r_y_p_t_e_d is not NULL then
it may be used as prototype for generated password.
Matching: full passphrase. (userflags are ignored)
NKCH "nneeww--llnnaammee" MASK
(int) void func(char *_n_e_w_l_n, char *_o_l_d_l_n);
Used when user Lname _o_l_d_l_n changed to Lname _n_e_w_l_n or if that _o_l_d_l_n is
deleted from Listfile.
Matching: old Lname. (userflags are ignored)
Script args: oldln newln
LOAD "llooaadd" MASK
(int) void func(char *_m_o_d, char *_a_r_g_s);
Used when module with name _m_o_d was succesfully loaded with arguments
_a_r_g_s.
Matching: module name with arguments.
Script args: mod
UNLD "uunnllooaadd" MASK
(int) void func(char *_m_o_d);
Used when module with name _m_o_d was terminated.
Matching: module name.
Script args: mod
- "llooggiinn" MASK
(int) void func(char *_w_h_o, char *_i_d_e_n_t, const char *_h_o_s_t,
struct peer_t *_p_e_e_r, char _b_u_f[SHORT_STRING],
char **_m_s_g);
Used when connection with someone is established and we got their
Lname _w_h_o. The binding is always called from thread but dispatcher is
locked so very first thing the binding must do is to make call
Unset_Iface(). Connection chain is already created, filter 'x' is
included, and it is bound to _p_e_e_r but there is no 'iface' or 'priv'
fields set in it. If required then binding makes password checking,
creates an interface if there were no errors and changes _p_e_e_r state
to something other than P_DISCONNECTED or P_INITIAL. In case of error
it should return an error message in _m_s_g so _p_e_e_r will be destroyed on
return. Parameters _i_d_e_n_t, and _h_o_s_t are coming from peer connection
socket. If _b_u_f contains empty string then it's telnet session. Buffer
_b_u_f can be used by the binding. Note: the binding must be
thread-safe! Don't use it please, until you know how it works!!!
Matching: network type. (any channel userflags are ignored)
- "ccoonnnneecctt" MASK
int func(const char *_l_i_n_k, char *_a_r_g_s);
Used on "connect" command to network/server/channel/bot _l_i_n_k with
optional parameters _a_r_g_s. Note that channel has the same type as
it's network but binding for connect channel must have any channel
userflag instead of some global userflags.
Matching: link's network type.
- "rreeggiisstteerr" MASK
int func(const char *_n_a_m_e, void *_v_a_r, size_t _s_i_z_e);
Used when any module attempts to register any variable _v_a_r (_s_i_z_e is
1 for bool, 0 for long int, 2 for read-only null-terminated string
or >2 for regular string) with symbolic name _n_a_m_e.
Matching: none
- "uunnrreeggiisstteerr" MASK
int func(const char *_n_a_m_e);
Used when any module attempts to unregister any variable _v_a_r with
symbolic name _n_a_m_e.
Matching: none
- "ffuunnccttiioonn" MASK
int func(const char *_n_a_m_e, int (* _f_n) (const char *));
Used when any module attempts to register any function _f_n with
symbolic name _n_a_m_e.
Matching: none
- "uunnffuunnccttiioonn" MASK
int func(const char *_n_a_m_e);
Used when any module attempts to unregister any function with
symbolic name _n_a_m_e.
Matching: none
- "ssccrriipptt" UNIQMASK
int func(char *_n_a_m_e);
Used when config parser attempts to load script file _n_a_m_e.
Matching: filename.
- "iissoonn" UNIQ
int func(const char *_n_e_t, const char *_p_u_b_l_i_c, const char *_l_n_a_m_e,
const char **_n_a_m_e);
Used by Lname_IsOn() function for calling network-specific procedure
for community _p_u_b_l_i_c on the network _n_e_t. If _p_u_b_l_i_c is NULL then
check should be performed for network itself. See description of the
Lname_IsOn() function for more details.
Matching: network type.
- "iinnssppeecctt--cclliieenntt" UNIQ
(int) modeflag func(const char *_n_e_t, const char *_p_u_b_l_i_c,
const char *_n_a_m_e, const char **_l_n_a_m_e,
const char **_h_o_s_t, time_t *_i_d_l_e, short *_c_n_t);
Used by Inspect_Client() function for calling network-specific
procedure for community _p_u_b_l_i_c on the network _n_e_t. If _p_u_b_l_i_c is NULL
then check should be performed for network itself. See description of
the Inspect_Client() function for more details.
Matching: network type.
- "uuppddaattee--ppuubblliicc" UNIQ
int func(const char *_n_e_t, const char *_p_u_b_l_i_c, modeflag _c_h_a_n_g_e,
const char *_t_g_t, const char *_t_o_p_i_c, const char *_b_y,
time_t _a_t);
Used by Update_Public() function for calling a network-specific
procedure for community _p_u_b_l_i_c on the network _n_e_t to update either
_t_o_p_i_c of community, or its mode in accordance with flags _c_h_a_n_g_e and
change target _t_g_t. Values _b_y and _a_t are related to the _t_o_p_i_c and may
be ignored by the binding. See description of the Update_Public()
function for more details.
Matching: network type.
- "ttiimmee--sshhiifftt" MASK
(int) void func(int _d_e_l_t_a);
Used when system time slipped (due to time correction or freezing).
Binding gets value of time shift _d_e_l_t_a in seconds.
Matching: none.
- "ccoonnnncchhaaiinn--ggrrooww" MATCHCASE
int func(struct peer_t *_p_e_e_r, ssize_t (**_r_e_c_v)(struct connchain_i **, idx_t,
char *, size_t, struct connchain_buffer **),
ssize_t (**_s_e_n_d)(struct connchain_i **, idx_t, const char *,
size_t *, struct connchain_buffer **),
struct connchain_buffer **_b_u_f);
Used when Connchain_Grow() function is called. It tries to setup a
connection chain link for some _p_e_e_r. Value of _p_e_e_r can be used for
identification on the setup or for notification to its interface (by
sending signal to it) in case when module which handles this filter
is terminated. Binding also can set field 'connchain' in the _p_e_e_r to
NULL and call Connchain_Grow() to reset it to empty chain but binding
itself should kill connection chain which was there before and that
kill is mandatory. Any other usage of this value is prohibited. The
_r_e_c_v and _s_e_n_d are pointers to handlers for receiving and sending data
through the link respectively and _b_u_f is pointer where this binding
have to store link instance's own buffer structure, this pointer will
be passed to the _r_e_c_v() and _s_e_n_d() handlers later. If there were no
errors then all three those pointers must be set by the binding. Also
there is a special case when _b_u_f is NULL, in that case binding should
do checks needed to setup a connection chain link but do not setup it
really. Returns 1 in case of success or 0 otherwise. Note: handler
_r_e_c_v() should be thread-safe and handler _s_e_n_d() should be async-safe,
be careful!
If binding mask is not just char but char with asterisk (i.e. "S*"
for example) then every link created by the binding will tag that
connection chain as "sticky", i.e. that part of the chain becomes
bound to the _p_e_e_r which it was created for and when some binding will
try to recreate connection chain that "sticky" chain will be moved to
newly created chain and will be never destroyed outside of that newly
created chain.
Arguments for _r_e_c_v() are: pointer for passing to Connchain_Get();
socket identifier; pointer to receiving buffer; size of that buffer;
pointer to this instance's own buffer. If _r_e_c_v() got NULL pointer to
receiving buffer then it have to destroy own buffer. If it get an
error from next link it should do the same and in both cases return
error and after that neither _r_e_c_v() nor _s_e_n_d() ever will be called
again. Else should return number of received bytes. If _r_e_c_v() got -1
as socket identifier then it have to return raw data from own buffer
and if that buffer is empty then pass call to next link.
Arguments for _s_e_n_d() are: pointer for passing to Connchain_Put();
socket identifier; pointer to sending buffer; pointer to counter of
bytes to send; pointer to instance's own buffer. If _s_e_n_d() got NULL
pointer to sending buffer then it have to try to send what is still
left in own buffer and return 0. If own buffer is empty then _s_e_n_d()
should return error code from next link in chain. If _s_e_n_d() got
pointer to sending buffer not equal to NULL but count of bytes to
send equal to 0 then it should return value CONNCHAIN_READY if it can
take data for sending on next call (that includes checking next link
in chain for ability to work) or some other value otherwise. If there
were no errors then _s_e_n_d() should return number of bytes were sent
and change counter (by argument's pointer) appropriately. The _s_e_n_d()
function should never close or destroy the socket.
Matching: connchain flag char.
Matching stops after first succesful binding call.
- "ggoott--lliisstteenneerr" UNIQMASK
int func(struct sockaddr *_s_a, int _s_e_t);
Used when Listen_Port() succesfully opened listener on some port.
The binding is called with _s_e_t equal to 1 from listening thread
which has cancelling state enabled at that moment. The binding is
called before of call of the backcall function (see description of
Listen_Port() for details) with the same sctructure _s_a and binding
have full access to it. This binding call is implemented for purpose
if we are behind NAT and binding can make some calls to NAT firewall
to make a DNAT port forwarding (UPnP can do it for example). Binding
also called from main thread with _s_e_t equal to 0 after listener was
terminated but only port is set in _s_a this time.
Matching: anything.
Module "irc-channel":
---------------------
Interfaces: accepts messages for I_SERVICE and name <channel>@<network>
to send them to channel (_c_h_a_n below).
JOIN "iirrcc--jjooiinn" MASK
(int) void func(unsigned char *_w_h_o, const char *_l_n_a_m_e,
INTERFACE *_c_h_a_n);
Used when someone _l_n_a_m_e with nick!user@host _w_h_o joins IRC channel
_c_h_a_n. Note: matching uses network+global flags instead of global
ones.
Matching: "channel nick!user@host" string.
Script args: nick user@host Lname channel
PART "iirrcc--ppaarrtt" MASK
(int) void func(unsigned char *_w_h_o, const char *_l_n_a_m_e,
INTERFACE *_c_h_a_n, char *_m_s_g);
Used when someone _l_n_a_m_e with nick!user@host _w_h_o parts IRC channel
_c_h_a_n with reason _m_s_g. Note: matching uses network+global flags
instead of global ones.
Matching: "channel nick!user@host" string.
Script args: nick user@host Lname channel msg
KICK "iirrcc--kkiicckk" MASK
(int) void func(unsigned char *_o_p, const char *_l_n_a_m_e, INTERFACE *_c_h_a_n,
unsigned char *_w_h_o, char *_c_o_m_m_e_n_t);
Used when someone _l_n_a_m_e with nick!user@host _o_p kicks nick _w_h_o from
channel _c_h_a_n with reason _c_o_m_m_e_n_t.
Matching: "channel who" string. (userflags are ignored)
Script args: op user@host Lname channel who comment
TOPC "iirrcc--ttooppiicc" MASK
(int) void func(unsigned char *_w_h_o, const char *_l_n_a_m_e,
INTERFACE *_c_h_a_n, char *_t_o_p_i_c);
Used when we got new topic info (on join or topic change). Note:
matching uses network+global flags instead of global ones.
Matching: "channel topic" string.
Script args: nick user@host Lname channel topic
MODE "iirrcc--mmooddeecchhgg" MASK
(int) void func(unsigned char *_w_h_o, const char *_l_n_a_m_e,
INTERFACE *_c_h_a_n, char *_c_h_g);
Used when someone _l_n_a_m_e with nick!user@host _w_h_o made mode change _c_h_g
on IRC channel _c_h_a_n. Note: matching uses network+global flags instead
of global ones. Note2: mode change line from server is parsed and
separated before calling any binding.
Matching: full mode change line (i.e. with channel name).
Tcl args: nick user@host Lname channel chg
REJN "iirrcc--nneettjjooiinn" MASK
(int) void func(unsigned char *_w_h_o, const char *_l_n_a_m_e,
INTERFACE *_c_h_a_n);
Used when IRC netjoin was detected (i.e. netsplit is over) and
someone _l_n_a_m_e with nick!user@host _w_h_o returned to channel _c_h_a_n. Note:
matching uses network+global flags instead of global ones.
Matching: "chan who" string.
Script args: nick user@host Lname channel
- "kkeeyycchhaannggee" MASK
(int) void func(char *_p_u_b_l_i_c, unsigned char *_w_h_o, const char *_l_n_a_m_e,
userflag _c_f, char *_k_e_y);
Used not yet.
Module "irc-ctcp":
------------------
- "ccttccpp--ddcccc" MATCHCASE
int func(INTERFACE *_c_l_i_e_n_t, unsigned char *_w_h_o, char *_l_n_a_m_e, char *_m_s_g);
Used when we got a ctcp message which is subcommand of "DCC" that
came on IRC network for me from someone _c_l_i_e_n_t with nick!user@host
_w_h_o and who is identified as _l_n_a_m_e. _m_s_g is the full command line
with arguments.
Matching: command. (any channel flags are ignored)
Matching stops after first succesful binding call.
RCVD "ddcccc--ggoott" MASK
(int) void func(unsigned char *_w_h_o, char *_f_i_l_e_n_a_m_e);
Used when someone with nick!user@host _w_h_o successfully uploaded the
file _f_i_l_e_n_a_m_e to us.
Matching: Lname. (any channel flags are ignored)
Script args: Lname nick@net path
SENT "ddcccc--sseenntt" MASK
(int) void func(unsigned char *_w_h_o, char *_f_i_l_e_n_a_m_e);
Used when someone with nick!user@host _w_h_o successfully downloaded the
file _f_i_l_e_n_a_m_e from us.
Matching: Lname. (any channel flags are ignored)
Script args: Lname nick@net filename
Module "irc":
-------------
Interfaces: accepts messages for I_CLIENT with name <name>@<network> to
send them for any valid recipient in network (_c_l_i_e_n_t below);
accepts messages for I_SERVICE with name <network> to send them to the
server (_i_f_a_c_e or _n_e_t below).
RAW "iirrcc--rraaww" MATCHCASE
int func(INTERFACE *_i_f_a_c_e, char *_s_e_r_v_n_a_m_e, char *_m_e,
unsigned char *_p_r_e_f_i_x, int _n, char **_p_a_r_a_m_s,
size_t (*_l_c) (char *, const char *, size_t));
Used when we get any message from server _s_e_r_v_n_a_m_e on the network
_i_f_a_c_e. Optional _p_r_e_f_i_x is message source (see the RFC). Message is
parsed and binding gets own nick _m_e, number _n of _p_a_r_a_m_s, and server
specific case conversion function _l_c. Note: return value -1 of the
binding has unusual meaning: parameters are incorrect.
Matching: command. (any flags are ignored)
Matching stops after first succesful binding call.
Script args: network sender command (params)...
- "iirrcc--ccoonnnneecctteedd" MASK
(int) void func(INTERFACE *_i_f_a_c_e, char *_s_e_r_v_n_a_m_e, char *_n_i_c_k,
size_t (*_l_c) (char *, const char *, size_t));
Used when we are succesfully connected to server _s_e_r_v_n_a_m_e on some
network _i_f_a_c_e. Binding gets _n_i_c_k that we got and server-specific
case conversion function _l_c. Note: bindings may be recalled when the
module gets signal S_FLUSH so don't be alarmed.
Matching: network name. (any flags are ignored)
Script args: network servname nick
- "iirrcc--ddiissccoonnnneecctteedd" MASK
(int) void func(INTERFACE *_i_f_a_c_e, char *_s_e_r_v_n_a_m_e, char *_n_i_c_k,
size_t (*_l_c) (char *, const char *, size_t));
Used when we are disconnected from server _s_e_r_v_n_a_m_e on some network
_i_f_a_c_e. Binding gets _n_i_c_k that we have last and server-specific case
conversion function _l_c.
Matching: network name. (any flags are ignored)
Script args: network servname nick
PUBM "iirrcc--ppuubb--mmssgg--mmaasskk" MASK
(int) void func(INTERFACE *_c_l_i_e_n_t, unsigned char *_w_h_o, char *_l_n_a_m_e,
char *_u_n_i_c_k, char *_c_h_a_n, char *_m_s_g);
Used when we got a message _m_s_g that came for IRC channel _c_h_a_n from
someone _c_l_i_e_n_t with nick!user@host _w_h_o (_u_n_i_c_k is his/her nickname
that is converted to lower case) and is identified as _l_n_a_m_e. _c_h_a_n is
string in form "#channel@network" (in case of safe channels the name
"!chan@network" gets short name). Note: matching uses network+global
flags instead of global ones.
Matching: "chan msg" string.
Script args: nick user@host Lname chan@net msg
- "iirrcc--ppuubb--nnoottiiccee--mmaasskk" MASK
(int) void func(INTERFACE *_c_l_i_e_n_t, unsigned char *_w_h_o, char *_l_n_a_m_e,
char *_u_n_i_c_k, char *_c_h_a_n, char *_m_s_g);
Used the same as above but for notice.
PUB "iirrcc--ppuubb--mmssgg--ccmmdd" UNIQ
int func(INTERFACE *_c_l_i_e_n_t, unsigned char *_w_h_o, char *_l_n_a_m_e,
char *_u_n_i_c_k, char *_c_h_a_n, char *_m_s_g);
Used when we got a message that came for IRC channel _c_h_a_n from
someone _c_l_i_e_n_t with nick!user@host _w_h_o (_u_n_i_c_k is his/her nickname
that is converted to lower case) which is identified as _l_n_a_m_e if
that message may be interpreted as command. _c_h_a_n is string in form
"#channel@network" (in case of safe channels the name "!chan@network"
gets short name) and _m_s_g is arguments string to command. Note:
matching uses network+global flags instead of global ones.
Matching: command.
Script args: nick user@host Lname chan@net args
- "iirrcc--ppuubb--nnoottiiccee--ccmmdd" UNIQ
int func(INTERFACE *_c_l_i_e_n_t, unsigned char *_w_h_o, char *_l_n_a_m_e,
char *_u_n_i_c_k, char *_c_h_a_n, char *_m_s_g);
Used the same as above but for notice.
CTCP "iirrcc--ppuubb--mmssgg--ccttccpp" MATCHCASE
int func(INTERFACE *_c_l_i_e_n_t, unsigned char *_w_h_o, char *_l_n_a_m_e,
char *_u_n_i_c_k, char *_c_h_a_n, char *_m_s_g);
Used the same as above but for ctcp and with another script arguments
list.
Matching: command.
Matching stops after first succesful binding call.
Script args: nick user@host Lname chan@net command [args]
CTCR "iirrcc--ppuubb--nnoottiiccee--ccttccpp" MATCHCASE
int func(INTERFACE *_c_l_i_e_n_t, unsigned char *_w_h_o, char *_l_n_a_m_e,
char *_u_n_i_c_k, char *_c_h_a_n, char *_m_s_g);
Used the same as above but for ctcp notice.
MSGM "iirrcc--pprriivv--mmssgg--mmaasskk" MASK
(int) void func(INTERFACE *_c_l_i_e_n_t, unsigned char *_w_h_o, char *_l_n_a_m_e,
char *_u_n_i_c_k, char *_m_s_g);
Used when we got a message _m_s_g on IRC network that came for me from
someone _c_l_i_e_n_t with nick!user@host _w_h_o (_u_n_i_c_k is his/her nickname
that is converted to lower case) and is identified as _l_n_a_m_e. Note:
matching flags are global+network instead of just global and direct
service as service ones.
Matching: msg.
Script args: nick user@host Lname msg
NOTC "iirrcc--pprriivv--nnoottiiccee--mmaasskk" MASK
(int) void func(INTERFACE *_c_l_i_e_n_t, unsigned char *_w_h_o, char *_l_n_a_m_e,
char *_u_n_i_c_k, char *_m_s_g);
Used the same as above but for notice.
MSG "iirrcc--pprriivv--mmssgg--ccmmdd" UNIQ
int func(INTERFACE *_c_l_i_e_n_t, unsigned char *_w_h_o, char *_l_n_a_m_e,
char *_u_n_i_c_k, char *_m_s_g);
Used when we got a message that came on IRC network for me from
someone _c_l_i_e_n_t with nick!user@host _w_h_o (_u_n_i_c_k is his/her nickname
that is converted to lower case) which is identified as _l_n_a_m_e if
that message may be interpreted as command. _m_s_g is arguments string
to command. Note: matching flags are global+network instead of just
global and direct service as service ones.
Matching: command.
Script args: nick user@host Lname args
- "iirrcc--pprriivv--nnoottiiccee--ccmmdd" UNIQ
int func(INTERFACE *_c_l_i_e_n_t, unsigned char *_w_h_o, char *_l_n_a_m_e,
char *_u_n_i_c_k, char *_m_s_g);
Used the same as above but for notice.
CTCP "iirrcc--pprriivv--mmssgg--ccttccpp" MATCHCASE
int func(INTERFACE *_c_l_i_e_n_t, unsigned char *_w_h_o, char *_l_n_a_m_e,
char *_u_n_i_c_k, char *_m_s_g);
Used the same as above but for ctcp and with another script arguments
list.
Matching: command.
Matching stops after first succesful binding call.
Script args: nick user@host Lname mynick command [args]
CTCR "iirrcc--pprriivv--nnoottiiccee--ccttccpp" MATCHCASE
int func(INTERFACE *_c_l_i_e_n_t, unsigned char *_w_h_o, char *_l_n_a_m_e,
char *_u_n_i_c_k, char *_m_s_g);
Used the same as above but for notice ctcp.
FLUD "iirrcc--fflloooodd" MASK
int func(unsigned char *_w_h_o, char *_l_n_a_m_e, char *_f_t, char *_c_h_a_n);
Used before message from someone _l_n_a_m_e with nick!user@host _w_h_o are
checked for flood so if binding returns not 0 then message must skip
flood checking. If message target is IRC channel then name of that
channel is _c_h_a_n, else if target is me then _c_h_a_n contains NULL. Type
of flood _f_t may be one of "ctcp" or "msg".
Matching: flood type.
Matching stops after first succesful binding call.
Script args: nick user@host Lname ft chan
NICK "iirrcc--nniicckkcchhgg" MASK
(int) void func(INTERFACE *_n_e_t, char *_l_n_a_m_e, unsigned char *_w_h_o,
char *_l_c_o_l_d_n, char *_n_e_w_n, char *_l_c_n_e_w_n);
Used when someone with nick!user@host _w_h_o changes on IRC network
_n_e_t his/her nick to _n_e_w_n and is identified now as _l_n_a_m_e. _l_c_o_l_d_n and
_l_c_n_e_w_n are old and new nicknames respectively that are converted to
lower case. Note: matching uses network+global flags instead of
global ones. Note2: scripts are called for each channel separately
and script bindings will be called only if module "irc-channel" is
loaded, and channel flags are not ignored only for script bindings.
Matching: newnick.
Script args: oldn user@host Lname channel newn
SIGN "iirrcc--ssiiggnnooffff" MASK
(int) void func(INTERFACE *_n_e_t, char *_l_n_a_m_e, unsigned char *_w_h_o,
char *_l_c_n_i_c_k, char *_m_s_g);
Used when someone _l_n_a_m_e with nick!user@host _w_h_o leaves IRC network
_n_e_t with the reason _m_s_g. _l_c_n_i_c_k is user nickname that is converted
to lower case. Note: matching uses network+global flags instead of
global ones. Note2: scripts are called for each channel separately
and script bindings will be called only if "irc-channel" module is
loaded, and channel flags are not ignored only for script bindings.
Note3: Script bindings here are called too when someone was lost in
netsplit and in that case reason is undefined.
Matching: "nick!user@host" string.
Script args: nick user@host Lname channel msg
SPLT "iirrcc--nneettsspplliitt" MASK
(int) void func(INTERFACE *_n_e_t, char *_l_n_a_m_e, unsigned char *_w_h_o,
char *_l_c_n_i_c_k, char *_s_e_r_v_e_r_s);
Used when some IRC server splits out of another IRC server (_s_e_r_v_e_r_s
is string "left-server gone-server") on the network _n_e_t and someone
_l_n_a_m_e with nick!user@host _w_h_o has left our part of network. _l_c_n_i_c_k
is user nick that is converted to lower case. Note: matching uses
network+global flags instead of global ones. Note2: scripts are
called for each channel separately and any script bindings will be
called only if "irc-channel" module is loaded, and channel flags are
not ignored only for script bindings.
Matching: "nick!user@host" string.
Script args: nick user@host Lname channel
- "iirrcc--qquuiitt" MASK
int func(INTERFACE *_n_e_t, char *_b_u_f, size_t _s_z);
Used before sending a quit message to the server on the network _n_e_t.
Zero-terminated text in buffer _b_u_f (of size _s_z) may be rewritten by
internal binding.
Matching: network name. (any flags are ignored)
Script args: network text
Bind result: new text line.
Module "ircd-capab":
--------------------
- "iirrccdd--ccaappaabb" UNIQ
(int) void func (INTERFACE *_s_r_v, struct peer_t *_p_e_e_r, const char *_c_a_p);
Used when a local server _p_e_e_r indicates a supported capability _c_a_p or
removes it (on server disconnect). In latter case _c_a_p will be NULL.
_s_r_v is IRCD interface which can be used to send control messages
(commands).
Matching: capability. (userflags are ignored)
Module "ircd":
--------------
Interfaces: accepts messages for I_SERVICE with name <network> to run
them as if they came anywhere else from (_s_r_v below) but as exception
message can be some numeric and in that case it will be forwarded to
target user thru "ircd-do-numeric" bindtable, that message will be put
at end of target's queue. If message has no prefix then the server
itself will be assumed as message source.
accepts messages for I_CLIENT with name <name>@<network> to send them
to valid recipient in network (note: if <name> is "" then recipient is
every local user and if <name> is "*.*" then recipient is every local
server link); messages have to have prefix.
Note: Inspect_Client() function for this module is case-sensitive for
nicks or server names to be as fast as possible and avoid undesired
case conversions (but still case-insensitive for channel names). The
lname in returned data contains either nick of who set topic (if that
data are available), or ident of the user.
- "iirrccdd--aauutthh" MASK
int func(struct peer_t *_p_e_e_r, char *_u_s_e_r, char *_h_o_s_t, const char **_m_s_g,
modeflag *_u_m_o_d_e);
Used when listening socked just accepted connection from someone _p_e_e_r
and binding gets their _u_s_e_r and _h_o_s_t for authentication check (for
example, check if host is in SPAM hosts database). Binding is called
within thread so should use only thread-safe functions. Dispatcher is
locked on start so at first you have to call Unset_Iface() and then
perform all your checks. Connection chain for peer is initialized so
you can send something there (but that is not advisable because it
may ruin IRC protocol). If binding denies access for that client then
it should return 0 and leave reason message into _m_s_g. The binding may
also set some modeflag in initial _u_m_o_d_e if needed.
Matching: host. (userflags are ignored)
Matching stops after first access failure.
- "iirrccdd--rreeggiisstteerr--ccmmdd" UNIQ
int func(INTERFACE *_s_r_v, struct peer_t *_p_e_e_r, int _a_r_g_c, const char **_a_r_g_v);
Used when server got some message from client _p_e_e_r that have not
registered yet. Message is parsed and put into array _a_r_g_v so _a_r_g_c
contains number of parameters that was given to command. _p_e_e_r->dname
contains nick of _p_e_e_r. _s_r_v is IRCD interface which can be used to
send control messages (commands). This bindtable is designed mostly
for internal "ircd" module usage so may be not so useful.
Matching: command. (userflags are ignored)
- "iirrccdd--cclliieenntt--ccmmdd" UNIQ
int func(INTERFACE *_s_r_v, struct peer_t *_p_e_e_r, const char *_l_c_n_i_c_k,
const char *_u_s_e_r, const char *_h_o_s_t, const char *_v_h_o_s_t,
modeflag _e_u_m, int _a_r_g_c, const char **_a_r_g_v);
Used when server got some message from local client _p_e_e_r. Message is
parsed and put into array _a_r_g_v so _a_r_g_c contains number of parameters
that was given to the command. _p_e_e_r->dname contains nick of sender,
_u_s_e_r and _h_o_s_t are from client connection, and converted to lower case
sender nick _l_c_n_i_c_k is provided to use with Inspect_Client() function.
The visible host _v_h_o_s_t and user mode flags _e_u_m effective for change
are also provided. _s_r_v is IRCD interface which can be used to send
control messages (commands). Value -1 returned by binding means this
command should not reset idle time calculation.
Matching: command. (channel userflags are ignored, used by HELP)
- "iirrccdd--sseerrvveerr--ccmmdd" KEYWORD
int func(INTERFACE *_s_r_v, struct peer_t *_p_e_e_r, unsigned short _t_o_k_e_n,
const char *_s_e_n_d_e_r, const char *_l_c_s_e_n_d_e_r, int _a_r_g_c,
const char **_a_r_g_v);
Used when server got some message from local server link _p_e_e_r (which
can be NULL if command invoked internally). Message is parsed and put
into array _a_r_g_v so _a_r_g_c contains number of parameters that was given
to the command. _p_e_e_r->dname contains name of _p_e_e_r, _s_e_n_d_e_r is supplied
by _p_e_e_r and is name of _p_e_e_r (or server's own name in case of _p_e_e_r is
NULL) if it was not provided in command. Converted to lower case
version of _s_e_n_d_e_r is also provided as _l_c_s_e_n_d_e_r for Inspect_Client()
function call. The _t_o_k_e_n of server of the _s_e_n_d_e_r is also provided.
_s_r_v is IRCD interface which can be used to send control messages
(commands). Value -1 returned by binding means this command should
not reset idle time calculation.
Matching: command. (userflags are ignored)
- "iirrccdd--llooccaall--cclliieenntt" MASK
(int) void func (INTERFACE *_s_r_v, struct peer_t *_p_e_e_r, modeflag _u_m);
Used when an user _p_e_e_r has been succesfully registered on the server
and propagated to others. _s_r_v is IRCD interface which can be used to
send control messages (commands). User mode _u_m also provided for any
checks.
Matching: user nick. (channel userflags are ignored)
- "iirrccdd--cclliieenntt" MASK
(int) void func (INTERFACE *_s_r_v, const char *_f_r_o_m, const char *_l_c_n_i_c_k,
const char *_n_i_c_k, const char *_n_n_i_c_k, const char *_u_s_e_r,
const char *_h_o_s_t, const char *_f_n_a_m_e, modeflag _u_m,
unsigned int _l_e_f_t);
Used when list of names in the network was changed, i.e. either user
or service succesfully entered network, left network, or user changed
their nick name. Binding is supplied with last seen _n_i_c_k of client,
connection parameters _u_s_e_r and _h_o_s_t, full name _f_n_a_m_e, umode _u_m, and
server which client was connected _f_r_o_m before the change happened.
If that is new client then binding gets _n_i_c_k equal to NULL. In that
case or in case of nick change _n_n_i_c_k will contain new user nick or
service name. As binding can be used for services too, in that case
parameters _u_s_e_r and _h_o_s_t will be empty strings. Parameter _l_e_f_t is
total number of clients known for the server at the event time, that
number includes every server, service, user, incomplete connection,
and every nick, remembered due to network splits or nick collision
reasons. Converted to lower case _n_i_c_k is also supplied for binding as
_l_c_n_i_c_k. _s_r_v is IRCD interface which can be used to send control
messages (commands).
Macthing: user nick. (userflags are ignored)
- "iirrccdd--ddoo--nnuummeerriicc" UNIQ
int func (INTERFACE *_s_r_v, int _n, const char *_n_i_c_k, modeflag _u_m,
char *_m_s_g);
Used when module "ircd" is about to send some numeric message which
has number _n and text _m_s_g for user _n_i_c_k which has umode _u_m so binding
can cancel sending it or do that itself, in that case binding should
return a non-zero value. _s_r_v is IRCD interface which can be used to
send control messages (commands).
Matching: numeric. (userflags are ignored)
- "iirrccdd--cchhaannnneell" UNIQ
(int) modeflag func(INTERFACE *_u, modeflag _u_m_o_d_e, modeflag _c_h_m_o_d_e,
int _c_o_u_n_t, const char *_c_h_n_a_m_e, NODE *_c_l,
const char **_t_o_c_r_e_a_t_e);
Used when some user _u which has mode _u_m_o_d_e attempts to join channel
_c_h_n_a_m_e which has mode _c_h_m_o_d_e and _c_o_u_n_t users in it. If _c_h_m_o_d_e is equal
to 0 (i.e. channel does not exist) and user is allowed to create new
channel then puts new (which is in static array) channel name into
_t_o_c_r_e_a_t_e but be sure to check _c_h_m_o_d_e too since channel may not exist
but be on hold. Binding can perform channel type specific checking
on channels list _c_l. Returns modes which should be set on channel
for user if user is allowed to join or 0 if isn't. Used also when
user leaves channel, in that case _t_o_c_r_e_a_t_e pointer is NULL, binding
returns new channel's modeflag after that leave (so if it's 0 then
channel should be destroyed). Interface _u can be used to send channel
specific notes (numerics) to the local user, those numerics will
never go through bindtable "ircd-do-numeric". That _u pointer is NULL
if this is remote user.
Matching: channel name's first char. (userflags are ignored)
- "iirrccdd--cchheecckk--mmeessssaaggee" MASK
int func(modeflag _u_m_o_d_e, modeflag _m_m_o_d_e, char *_m_s_g);
Used when someone with channel mode _u_m_o_d_e is trying to send a message
_m_s_g into some channel with modes _m_m_o_d_e. Returns 1 in case if sending
is allowed, -1 if it may be allowed (i.e. allowed until other binding
disallowed it), or 0 if it is disallowed. If no appropriate binding
was found then message will be allowed.
Matching: target. (userflags are ignored)
Matching stops after first binding call that returns 1.
- "iirrccdd--cchheecckk--mmooddeecchhaannggee" MASK
int func(INTERFACE *_u, modeflag _u_m_o_d_e, const char *_c_h_n, modeflag _c_m_o_d_e,
int _a_d_d, modeflag _c_h_g, const char *_t_g_t, modeflag _t_u_m_o_d_e,
modeflag _t_c_m_o_d_e);
Used when someone with channel mode _u_m_o_d_e trying to make a modechange
_c_h_g for some target _t_g_t which has user mode _t_u_m_o_d_e and channel mode
_t_c_m_o_d_e on the channel _c_h_n with modes _m_m_o_d_e. Binding gets modechange
which consists of all mode flags received from all matching bindings
of "ircd-modechange" bindtable. _a_d_d indicates direction of the change
and is 0 in case if it is attempt to down mode and is 1 in case if it
is attempt to raise mode. Binding also may be called when user either
attempts to join channel or changes their nick, and in that case _t_g_t
is user nick, _u_m_o_d_e is user mode and _c_h_g is 0. In latter case if
binding denies the join, it should send a message to the user using
user interface _u (it's NULL if user is remote). Returns 0 in case
if modechange should be rejected or any other value otherwise.
Matching: channel name. (userflags are ignored)
Matching stops after first reject.
- "iirrccdd--mmooddeecchhaannggee" MATCHCASE
(int) modeflag func(modeflag _r_c_h_m_o_d_e, modeflag _r_m_o_d_e,
const char *_t_a_r_g_e_t, modeflag _t_m_o_d_e,
modeflag _t_u_m_o_d_e, int _a_d_d, char _c_h_t_y_p_e,
int (**_m_a)(INTERFACE *_s_r_v, const char *_r_q,
const char *_c_h, int _a_d_d,
const char **_p_a_r_a_m));
Used when some client which has channel mode _r_c_h_m_o_d_e and user mode
_r_m_o_d_e sent command for some mode change on channel of type _c_h_t_y_p_e in
direction _a_d_d (which is 0 if it's an attempt to down mode or 1 if
it's attempt to raise mode) for some _t_a_r_g_e_t on the channel which has
channel mode _t_m_o_d_e and user mode _t_u_m_o_d_e (see bindtable "ircd-whochar"
in regard of modechanges for users in channel). In case if it's
attempt of changing mode for the channel (itself) then _t_a_r_g_e_t is
NULL, and _t_m_o_d_e is channel mode. In case if that change requires a
parameter then _m_a on return should be filled with pointer to function
to set/clear/query the mode, in such case binding match mask should
be "X*". The function _m_a may get _a_d_d equal to -1 for mode query and
will get also channel name _c_h and parameter _p_a_r_a_m (and if it was a
mode query then no parameter _p_a_r_a_m is provided) for the requested
modechange. The function _m_a should return 1 on success, 0 on fail, or
-1 if change was ignored (if ban already exists for example). The
function _m_a can replace pointer to _p_a_r_a_m if it must be rewritten on
further mode broadcast. Since function _m_a is called only on actual
request, it may use interface _s_r_v to send numeric messages to the
client _r_q. The binding returns modeflag change for target if it's
approved combined with lowest bit set to 1 if that modechange should
consume a parameter (even if change isn't approved). If change is not
approved due to missing original channel creator privileges then
binding should set bit A_PINGED in returned value. The binding also
should support "test mode" when it is called with invalid value of
parameter _r_c_h_m_o_d_e equal to 0 and with appropriate value of _t_a_r_g_e_t, in
such case the binding should return appropriate mode flag, setting _m_a
isn't required. Note: you have to send S_FLUSH signal to modules
"ircd*" each time you adding or removing a binding so those modules
can build their list of all supported flags to reply to user on
request.
Matching: modechar. (userflags are ignored)
- "iirrccdd--uummooddeecchhaannggee" MATCHCASE
(int) modeflag func(modeflag _r_u_m_o_d_e, int _a_d_d,
void (**_m_a)(INTERFACE *_s_r_v, const char *_r_q,
char *_v_h_o_s_t, const char *_h_o_s_t,
size_t _v_h_s, int _a_d_d,
const char *_s_e_r_v_n_a_m_e));
Used when some client with given user mode _r_u_m_o_d_e sent command for
some mode change on themself in direction _a_d_d (which is 0 if it's an
attempt to down mode or 1 if it's attempt to raise mode). Returns
modeflag change if it approved. May return 1 if change is allowed but
should be ignored. The binding also should support "test mode" when
is called with invalid value of parameter _r_u_m_o_d_e equal to 0, in such
case the binding should return appropriate mode flag. There is also
special support for VHOST feature where visible host is different
from real one - binding should set a pointer to function which makes
such visible host into _m_a. Since function _m_a is called only on actual
request, it may use interface _s_r_v to send numeric messages to the
client _r_q. That function receives pointer (_v_h_o_s_t) and size _v_h_s of
visible host data buffer, real _h_o_s_t and direction _a_d_d, the name of
server for client is also provided as _s_e_r_v_n_a_m_e.
Matching: modechar. (userflags are ignored)
- "iirrccdd--wwhhoocchhaarr" MASK
(int) char func(char _m_o_d_e_c_h_a_r);
Used on start or S_FLUSH signal to make translation from modechange
character _m_o_d_e_c_h_a_r into character for WHO reply. You have to send
S_FLUSH signal to module "ircd" each time you adding or removing a
binding. Returns appropriate char or 0 if there is no one.
Matching: network name. (userflags are ignored)
- "iirrccdd--cclliieenntt--ffiilltteerr" KEYWORD
int func(INTERFACE *_s_r_v, struct peer_t *_p_e_e_r, modeflag _u_m_o_d_e, int _a_r_g_c,
const char **_a_r_g_v);
Used before "ircd-client-cmd" bindtable so you can intercept and
cancel executing any bindings in it by returning zero value. Binding
receives the same _s_r_v, _p_e_e_r, _a_r_g_c, and _a_r_g_v parameters that binding
for "ircd-client-cmd" will do and also user mode flags _u_m_o_d_e. Also
used before "ircd-register-cmd" so _a_r_g_v may vary and nick of the
client may be not known yet. Binding may return value bigger than 1
if it wants increased penalty for the message. If binding returns 0
(so denies executing) then no ERR_UNKNOWNCOMMAND will be sent so it's
in binding hands to send some numeric reply to user instead or simply
silently ignore the message.
Matching: command. (channel userflags are ignored)
Matching stops after first reject.
- "iirrccdd--ssttaattss--rreeppllyy" KEYWORD
(int) void func(INTERFACE *_s_r_v, const char *_r_q, modeflag _m_f);
Used when server got request STATS from some user which has nick _r_q
and user mode _m_f. _s_r_v is IRCD interface which can be used to send
control messages (commands).
Matching: STAT request parameter. (userflags are ignored)
- "iirrccdd--ccoolllliissiioonn" UNIQMASK
int func(INTERFACE *_s_r_v, char *_n_e_w, size_t _n_s_i_z_e, const char *_e_s_e_r_v,
const char *_n_s_e_r_v);
Used when server got nick collision for some nick _n_e_w. Binding have
to propose some solution to resolve this issue. If binding proposes
to kill both users then it should return -1. If binding proposes to
kill one of users then it should return 0 to keep existing user or 1
to keep colliding user. If binding proposes to rename a user then it
should make a nick for it in buffer _n_e_w of size _n_s_i_z_e and return 2 in
case if existing user should be renamed or 3 in case if colliding
user should be renamed. If that returned nick is indentical to any
existing one then the user will be not renamed but killed instead.
Server interface _s_r_v is provided so binding can make required checks.
Parameters _e_s_e_r_v and _n_s_e_r_v are names of servers of those existing and
colliding users, and in case if existing user is a local one, _e_s_e_r_v
will be NULL.
Matching: anything. (userflags are ignored)
- "iirrccdd--sseett--mmeessssaaggee--ttaarrggeettss" MASK
int func (INTERFACE *_s_r_v, const char *_s_e_n_d_e_r, const char *_t_a_r_g_e_t,
int (*_n_e_x_t)(INTERFACE *_s_r_v, const char *_m_a_s_k,
const char **_l_c_n_a_m_e, modeflag *_m_f, int **_m_a_r_k,
void **_i_t_e_r));
Used when server processes some message not for exact target name but
for a mask _t_a_r_g_e_t. Binding can process matching using function _n_e_x_t
which receives input _s_r_v, some _m_a_s_k that binding makes from _t_a_r_g_e_t,
and pointer _i_t_e_r to the iterator data (which should be set to NULL
initially). The function _n_e_x_t will return 0 when list is exhausted,
otherwise it will return 1 and set found client data: nick converted
to lower case _l_c_n_a_m_e and current modes _m_f for the original reguest
context. Binding also gets requestor nick _s_e_n_d_e_r. If binding decides
that found client matches criteria then it should set _m_a_r_k to 1.
Matching: target mask. (userflags are ignored)
- "iirrccdd--wwhhooiiss" MASK
(int) void func(INTERFACE *_s_r_v, const char *_s_e_n_d_e_r, modeflag _s_u_m_f,
const char *_t_a_r_g_e_t, const char *_t_h_o_s_t,
const char *_v_h_o_s_t, modeflag _t_u_m_f);
Used when server replies to a WHOIS query from some _s_e_n_d_e_r with user
mode _s_u_m_f for some _t_a_r_g_e_t which has host _t_h_o_s_t and user mode _t_u_m_f.
Binding can send some numeric reply then to the client using IRCD
interface _s_r_v.
Matching: target. (userflags are ignored)
- "iirrccdd--cchheecckk--sseenndd" MATCHCASE
int func(INTERFACE *_s_r_v, struct peer_t *_t_g_t, modeflag _t_u_m, char *_m_s_g,
size_t _m_s);
Used when message _m_s_g in buffer of size _m_s is about to be sent to a
local link _t_g_t which has mode _t_u_m at this moment. Binding can either
leave message intact, or rewrite the message, or put another message
for client using either interface pointer in _t_g_t or IRCD interface
_s_r_v. Note that message _m_s_g is in client's encoding. Also note that
message which is sent using interface pointer in _t_g_t will miss any
filtering (through "ircd-do-numeric" bindtable for example) but the
"ircd-check-send" filtering on next send. Returns 0 if the message
should be discarded.
Matching: message type (command). (userflags are ignored)
- "iirrccdd--iissuuppppoorrtt" MASK
(int) void func(char *_b_u_f_f, size_t _b_u_f_f_s_i_z_e);
Used when RPL_ISUPPORT going to be sent to client, so binding can add
some messages to it putting them into _b_u_f_f of _b_u_f_f_s_i_z_e.
Matching: own server name. (userflags are ignored)
- "iirrccdd--ggoott--sseerrvveerr" MASK
(int) void func (INTERFACE *_s_r_v, struct peer_t *_p_e_e_r, modeflag _u_m,
unsigned short _t_o_k_e_n, const char *_f_l_a_g_s);
Used when a server _p_e_e_r has been succesfully registered locally and
propagated to others. _s_r_v is IRCD interface which can be used to send
control messages (commands). Mode _u_m, server _t_o_k_e_n and negotiated
connection _f_l_a_g_s are also provided for any checks. This binding is
done before burst so binding can remember the server and module may
consider it in further processing.
Matching: server name. (userflags are ignored)
- "iirrccdd--lloosstt--sseerrvveerr" MASK
(int) void func (INTERFACE *_s_r_v, struct peer_t *_p_e_e_r);
Used when a local server _p_e_e_r is disconnecting from network. _s_r_v is
IRCD interface which can be used to send control messages (commands).
Matching: server name. (userflags are ignored)
- "iirrccdd--eeoobb" MASK
(int) void func(INTERFACE *_s_r_v, struct peer_t *_p_e_e_r,
const char *_c_h_n_a_m_e, modeflag _m_f, int _i_s___l_a_s_t);
Used when ircd has finished burst of a channel _c_h_n_a_m_e to the server
_p_e_e_r after initial handshake. Binding is provided with mode _m_f of the
channel. _i_s___l_a_s_t is TRUE if this was a last channel sent (therefore
it's end of whole burst). _s_r_v is IRCD interface which can be used to
send control messages (commands).
Matching: channel name. (userflags are ignored)
- "iirrccdd--ddrroopp--uunnkknnoowwnn" MASK
(int) void func(INTERFACE *_s_r_v, struct peer_t *_p_e_e_r, const char *_u_s_e_r,
const char *_h_o_s_t);
Used when some not registered yet client _p_e_e_r which had connection
parameters _u_s_e_r and _h_o_s_t disconnects from the server.
Matching: client's host. (userflags are ignored)
- "iirrccdd--sseerrvveerr--hhaannddsshhaakkee" MASK
int func(INTERFACE *_s_r_v, struct peer_t *_p_e_e_r, const char *_n_a_m_e);
Used before server sends a handshake message (PASS) to some _p_e_e_r
which presumably will be registered as a server (either uplink or
downlink). _p_e_e_r is fully functional and may be used to send messages.
Be aware that may disrupt IRC protocol and peer buffers may not have
enough space. Client _n_a_m_e and server interface _s_r_v are provided for
convenience. Returns length of message if any was sent.
Matching: peer's host. (userflags are ignored)
|