| 1632 |
} |
} |
| 1633 |
} |
} |
| 1634 |
|
|
| 1635 |
|
#if 1 |
| 1636 |
|
// TTXSamples/TTXCommandLineOpt/TTXCommandLineOpt.c と同じ |
| 1637 |
|
static PCHAR GetParam(PCHAR buff, int size, PCHAR param) { |
| 1638 |
|
int i = 0; |
| 1639 |
|
BOOL quoted = FALSE; |
| 1640 |
|
|
| 1641 |
|
while (*param == ' ' || *param == '\t') { |
| 1642 |
|
param++; |
| 1643 |
|
} |
| 1644 |
|
|
| 1645 |
|
if (*param == '\0' || *param == ';') { |
| 1646 |
|
return NULL; |
| 1647 |
|
} |
| 1648 |
|
|
| 1649 |
|
while (*param != '\0' && (quoted || (*param != ';' && *param != ' ' && *param != '\t'))) { |
| 1650 |
|
if (*param == '"' && (*++param != '"' || !quoted)) { |
| 1651 |
|
quoted = !quoted; |
| 1652 |
|
continue; |
| 1653 |
|
} |
| 1654 |
|
else if (i < size - 1) { |
| 1655 |
|
buff[i++] = *param; |
| 1656 |
|
} |
| 1657 |
|
param++; |
| 1658 |
|
} |
| 1659 |
|
|
| 1660 |
|
buff[i] = '\0'; |
| 1661 |
|
return (param); |
| 1662 |
|
} |
| 1663 |
|
|
| 1664 |
|
static void FAR PASCAL TTXParseParam(PCHAR param, PTTSet ts, PCHAR DDETopic) { |
| 1665 |
|
int param_len=strlen(param); |
| 1666 |
|
int opt_len = param_len+1; |
| 1667 |
|
char *option = (char *)calloc(opt_len, sizeof(char)); |
| 1668 |
|
int action; |
| 1669 |
|
PCHAR cur, next; |
| 1670 |
|
|
| 1671 |
|
if (pvar->hostdlg_activated) { |
| 1672 |
|
pvar->settings.Enabled = pvar->hostdlg_Enabled; |
| 1673 |
|
} |
| 1674 |
|
|
| 1675 |
|
cur = param; |
| 1676 |
|
while (next = GetParam(option, opt_len, cur)) { |
| 1677 |
|
action = OPTION_NONE; |
| 1678 |
|
|
| 1679 |
|
if ((option[0] == '-' || option[0] == '/')) { |
| 1680 |
|
if (MATCH_STR(option + 1, "ssh") == 0) { |
| 1681 |
|
if (MATCH_STR(option + 4, "-f=") == 0) { |
| 1682 |
|
read_ssh_options_from_user_file(pvar, option + 7); |
| 1683 |
|
action = OPTION_CLEAR; |
| 1684 |
|
} else if (MATCH_STR(option + 4, "-consume=") == 0) { |
| 1685 |
|
read_ssh_options_from_user_file(pvar, option + 13); |
| 1686 |
|
DeleteFile(option + 13); |
| 1687 |
|
action = OPTION_CLEAR; |
| 1688 |
|
} |
| 1689 |
|
|
| 1690 |
|
// ttermpro.exe の /F= 指定でも TTSSH の設定を読む (2006.10.11 maya) |
| 1691 |
|
} else if (MATCH_STR_I(option + 1, "f=") == 0) { |
| 1692 |
|
read_ssh_options_from_user_file(pvar, option + 3); |
| 1693 |
|
// Tera Term側でも解釈する必要があるので消さない |
| 1694 |
|
} |
| 1695 |
|
} |
| 1696 |
|
|
| 1697 |
|
switch (action) { |
| 1698 |
|
case OPTION_CLEAR: |
| 1699 |
|
memset(cur, ' ', next-cur); |
| 1700 |
|
break; |
| 1701 |
|
case OPTION_REPLACE: |
| 1702 |
|
memset(cur, ' ', next-cur); |
| 1703 |
|
memcpy(cur+1, option, strlen(option)); |
| 1704 |
|
break; |
| 1705 |
|
} |
| 1706 |
|
|
| 1707 |
|
cur = next; |
| 1708 |
|
} |
| 1709 |
|
|
| 1710 |
|
cur = param; |
| 1711 |
|
while (next = GetParam(option, opt_len, cur)) { |
| 1712 |
|
action = OPTION_NONE; |
| 1713 |
|
|
| 1714 |
|
if ((option[0] == '-' || option[0] == '/')) { |
| 1715 |
|
action = OPTION_CLEAR; |
| 1716 |
|
if (MATCH_STR(option + 1, "ssh") == 0) { |
| 1717 |
|
if (option[4] == 0) { |
| 1718 |
|
pvar->settings.Enabled = 1; |
| 1719 |
|
} else if (MATCH_STR(option + 4, "-L") == 0 || |
| 1720 |
|
MATCH_STR(option + 4, "-R") == 0 || |
| 1721 |
|
_stricmp(option + 4, "-X") == 0) { |
| 1722 |
|
add_forward_param(pvar, option+5); |
| 1723 |
|
} else if (MATCH_STR(option + 4, "-X") == 0) { |
| 1724 |
|
add_forward_param(pvar, "X"); |
| 1725 |
|
strncpy_s(pvar->settings.X11Display, |
| 1726 |
|
sizeof(pvar->settings.X11Display), |
| 1727 |
|
option + 6, _TRUNCATE); |
| 1728 |
|
} else if (MATCH_STR(option + 4, "-v") == 0) { |
| 1729 |
|
pvar->settings.LogLevel = LOG_LEVEL_VERBOSE; |
| 1730 |
|
} else if (_stricmp(option + 4, "-autologin") == 0 || |
| 1731 |
|
_stricmp(option + 4, "-autologon") == 0) { |
| 1732 |
|
pvar->settings.TryDefaultAuth = TRUE; |
| 1733 |
|
} else if (MATCH_STR_I(option + 4, "-agentconfirm=") == 0) { |
| 1734 |
|
if ((_stricmp(option+18, "off") == 0) || |
| 1735 |
|
(_stricmp(option+18, "no") == 0) || |
| 1736 |
|
(_stricmp(option+18, "false") == 0) || |
| 1737 |
|
(_stricmp(option+18, "0") == 0) || |
| 1738 |
|
(_stricmp(option+18, "n") == 0)) { |
| 1739 |
|
pvar->settings.ForwardAgentConfirm = 0; |
| 1740 |
|
} |
| 1741 |
|
else { |
| 1742 |
|
pvar->settings.ForwardAgentConfirm = 1; |
| 1743 |
|
} |
| 1744 |
|
|
| 1745 |
|
// -axxより上にしてはだめ |
| 1746 |
|
} else if (MATCH_STR(option + 4, "-a") == 0) { |
| 1747 |
|
pvar->settings.ForwardAgent = FALSE; |
| 1748 |
|
} else if (MATCH_STR(option + 4, "-A") == 0) { |
| 1749 |
|
pvar->settings.ForwardAgent = TRUE; |
| 1750 |
|
|
| 1751 |
|
} else if (MATCH_STR(option + 4, "-C=") == 0) { |
| 1752 |
|
pvar->settings.CompressionLevel = atoi(option+7); |
| 1753 |
|
if (pvar->settings.CompressionLevel < 0) { |
| 1754 |
|
pvar->settings.CompressionLevel = 0; |
| 1755 |
|
} |
| 1756 |
|
else if (pvar->settings.CompressionLevel > 9) { |
| 1757 |
|
pvar->settings.CompressionLevel = 9; |
| 1758 |
|
} |
| 1759 |
|
} else if (MATCH_STR(option + 4, "-C") == 0) { |
| 1760 |
|
pvar->settings.CompressionLevel = 6; |
| 1761 |
|
} else if (MATCH_STR(option + 4, "-c") == 0) { |
| 1762 |
|
pvar->settings.CompressionLevel = 0; |
| 1763 |
|
} else if (MATCH_STR_I(option + 4, "-icon=") == 0) { |
| 1764 |
|
if ((_stricmp(option+10, "old") == 0) || |
| 1765 |
|
(_stricmp(option+10, "yellow") == 0) || |
| 1766 |
|
(_stricmp(option+10, "securett_yellow") == 0)) { |
| 1767 |
|
pvar->settings.IconID = IDI_SECURETT_YELLOW; |
| 1768 |
|
} |
| 1769 |
|
else { |
| 1770 |
|
pvar->settings.IconID = IDI_SECURETT; |
| 1771 |
|
} |
| 1772 |
|
|
| 1773 |
|
// /ssh1 と /ssh2 オプションの新規追加 (2006.9.16 maya) |
| 1774 |
|
} else if (MATCH_STR(option + 4, "1") == 0) { |
| 1775 |
|
pvar->settings.Enabled = 1; |
| 1776 |
|
pvar->settings.ssh_protocol_version = 1; |
| 1777 |
|
} else if (MATCH_STR(option + 4, "2") == 0) { |
| 1778 |
|
pvar->settings.Enabled = 1; |
| 1779 |
|
pvar->settings.ssh_protocol_version = 2; |
| 1780 |
|
|
| 1781 |
|
} else { |
| 1782 |
|
char buf[1024]; |
| 1783 |
|
|
| 1784 |
|
UTIL_get_lang_msg("MSG_UNKNOWN_OPTION_ERROR", pvar, |
| 1785 |
|
"Unrecognized command-line option: %s"); |
| 1786 |
|
_snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, option); |
| 1787 |
|
|
| 1788 |
|
MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION); |
| 1789 |
|
} |
| 1790 |
|
|
| 1791 |
|
// ttermpro.exe の /T= 指定の流用なので、大文字も許す (2006.10.19 maya) |
| 1792 |
|
} else if (MATCH_STR_I(option + 1, "t=") == 0) { |
| 1793 |
|
if (strcmp(option + 3, "2") == 0) { |
| 1794 |
|
pvar->settings.Enabled = 1; |
| 1795 |
|
// /t=2はttssh側での拡張なので消す |
| 1796 |
|
} else { |
| 1797 |
|
pvar->settings.Enabled = 0; |
| 1798 |
|
action = OPTION_NONE; // Tera Term側で解釈するので消さない |
| 1799 |
|
} |
| 1800 |
|
|
| 1801 |
|
// /1 および /2 オプションの新規追加 (2004.10.3 yutaka) |
| 1802 |
|
} else if (MATCH_STR(option + 1, "1") == 0) { |
| 1803 |
|
// command line: /ssh /1 is SSH1 only |
| 1804 |
|
pvar->settings.ssh_protocol_version = 1; |
| 1805 |
|
|
| 1806 |
|
} else if (MATCH_STR(option + 1, "2") == 0) { |
| 1807 |
|
// command line: /ssh /2 is SSH2 & SSH1 |
| 1808 |
|
pvar->settings.ssh_protocol_version = 2; |
| 1809 |
|
|
| 1810 |
|
} else if (MATCH_STR(option + 1, "nossh") == 0) { |
| 1811 |
|
// '/nossh' オプションの追加。 |
| 1812 |
|
// TERATERM.INI でSSHが有効になっている場合、うまくCygtermが起動しないことが |
| 1813 |
|
// あることへの対処。(2004.10.11 yutaka) |
| 1814 |
|
pvar->settings.Enabled = 0; |
| 1815 |
|
|
| 1816 |
|
} else if (MATCH_STR(option + 1, "telnet") == 0) { |
| 1817 |
|
// '/telnet' が指定されているときには '/nossh' と同じく |
| 1818 |
|
// SSHを無効にする (2006.9.16 maya) |
| 1819 |
|
pvar->settings.Enabled = 0; |
| 1820 |
|
// Tera Term の Telnet フラグも付ける |
| 1821 |
|
pvar->ts->Telnet = 1; |
| 1822 |
|
|
| 1823 |
|
} else if (MATCH_STR(option + 1, "auth") == 0) { |
| 1824 |
|
// SSH2自動ログインオプションの追加 |
| 1825 |
|
// |
| 1826 |
|
// SYNOPSIS: /ssh /auth=passowrd /user=ユーザ名 /passwd=パスワード |
| 1827 |
|
// /ssh /auth=publickey /user=ユーザ名 /passwd=パスワード /keyfile=パス |
| 1828 |
|
// EXAMPLE: /ssh /auth=password /user=nike /passwd=a@bc |
| 1829 |
|
// /ssh /auth=publickey /user=foo /passwd=bar /keyfile=d:\tmp\id_rsa |
| 1830 |
|
// NOTICE: パスワードやパスに空白が含む場合は、ブランクの代わりに @ を使うこと。 |
| 1831 |
|
// |
| 1832 |
|
// (2004.11.30 yutaka) |
| 1833 |
|
// (2005.1.26 yutaka) 空白対応。公開鍵認証サポート。 |
| 1834 |
|
// |
| 1835 |
|
pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka) |
| 1836 |
|
|
| 1837 |
|
if (MATCH_STR(option + 5, "=password") == 0) { // パスワード |
| 1838 |
|
//pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD; |
| 1839 |
|
pvar->ssh2_authmethod = SSH_AUTH_PASSWORD; |
| 1840 |
|
|
| 1841 |
|
// /auth=challenge を追加 (2007.10.5 maya) |
| 1842 |
|
} else if (MATCH_STR(option + 5, "=challenge") == 0) { // keyboard-interactive認証 |
| 1843 |
|
//pvar->auth_state.cur_cred.method = SSH_AUTH_TIS; |
| 1844 |
|
pvar->ssh2_authmethod = SSH_AUTH_TIS; |
| 1845 |
|
|
| 1846 |
|
} else if (MATCH_STR(option + 5, "=publickey") == 0) { // 公開鍵認証 |
| 1847 |
|
//pvar->auth_state.cur_cred.method = SSH_AUTH_RSA; |
| 1848 |
|
pvar->ssh2_authmethod = SSH_AUTH_RSA; |
| 1849 |
|
|
| 1850 |
|
} else if (MATCH_STR(option + 5, "=pageant") == 0) { // 公開鍵認証 by Pageant |
| 1851 |
|
//pvar->auth_state.cur_cred.method = SSH_AUTH_RSA; |
| 1852 |
|
pvar->ssh2_authmethod = SSH_AUTH_PAGEANT; |
| 1853 |
|
|
| 1854 |
|
} else { |
| 1855 |
|
// TODO: |
| 1856 |
|
|
| 1857 |
|
} |
| 1858 |
|
|
| 1859 |
|
} else if (MATCH_STR(option + 1, "user=") == 0) { |
| 1860 |
|
_snprintf_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), _TRUNCATE, "%s", option + 6); |
| 1861 |
|
|
| 1862 |
|
} else if (MATCH_STR(option + 1, "passwd=") == 0) { |
| 1863 |
|
_snprintf_s(pvar->ssh2_password, sizeof(pvar->ssh2_password), _TRUNCATE, "%s", option + 8); |
| 1864 |
|
|
| 1865 |
|
} else if (MATCH_STR(option + 1, "keyfile=") == 0) { |
| 1866 |
|
_snprintf_s(pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile), _TRUNCATE, "%s", option + 9); |
| 1867 |
|
|
| 1868 |
|
} else if (MATCH_STR(option + 1, "ask4passwd") == 0) { |
| 1869 |
|
// パスワードを聞く (2006.9.18 maya) |
| 1870 |
|
pvar->ask4passwd = 1; |
| 1871 |
|
|
| 1872 |
|
} else if (MATCH_STR(option + 1, "nosecuritywarning") == 0) { |
| 1873 |
|
// known_hostsチェックをしない。当該オプションを使うと、セキュリティ性が低下する |
| 1874 |
|
// ため、隠しオプション扱いとする。 |
| 1875 |
|
// (2009.10.4 yutaka) |
| 1876 |
|
pvar->nocheck_known_hosts = TRUE; |
| 1877 |
|
|
| 1878 |
|
} |
| 1879 |
|
else { // Other (not ttssh) option |
| 1880 |
|
action = OPTION_NONE; // ttsshのオプションではないので消さない |
| 1881 |
|
} |
| 1882 |
|
|
| 1883 |
|
// パスワードを聞く場合は自動ログインが無効になる |
| 1884 |
|
// /auth は認証メソッドの指定としては利用される (2006.9.18 maya) |
| 1885 |
|
if (pvar->ask4passwd == 1) { |
| 1886 |
|
pvar->ssh2_autologin = 0; |
| 1887 |
|
} |
| 1888 |
|
|
| 1889 |
|
} |
| 1890 |
|
else if ((MATCH_STR_I(option, "ssh://") == 0) || |
| 1891 |
|
(MATCH_STR_I(option, "ssh1://") == 0) || |
| 1892 |
|
(MATCH_STR_I(option, "ssh2://") == 0) || |
| 1893 |
|
(MATCH_STR_I(option, "slogin://") == 0) || |
| 1894 |
|
(MATCH_STR_I(option, "slogin1://") == 0) || |
| 1895 |
|
(MATCH_STR_I(option, "slogin2://") == 0)) { |
| 1896 |
|
// |
| 1897 |
|
// ssh://user@host/ 等のURL形式のサポート |
| 1898 |
|
// 基本的な書式は telnet:// URLに順ずる |
| 1899 |
|
// |
| 1900 |
|
// 参考: |
| 1901 |
|
// RFC3986: Uniform Resource Identifier (URI): Generic Syntax |
| 1902 |
|
// RFC4248: The telnet URI Scheme |
| 1903 |
|
// |
| 1904 |
|
char *p, *p2, *p3; |
| 1905 |
|
int optlen, hostlen; |
| 1906 |
|
|
| 1907 |
|
optlen = strlen(option); |
| 1908 |
|
|
| 1909 |
|
// 最初の':'の前の文字が数字だった場合、それをsshプロトコルバージョンとみなす |
| 1910 |
|
p = _mbschr(option, ':'); |
| 1911 |
|
switch (*(p-1)) { |
| 1912 |
|
case '1': |
| 1913 |
|
pvar->settings.ssh_protocol_version = 1; |
| 1914 |
|
break; |
| 1915 |
|
case '2': |
| 1916 |
|
pvar->settings.ssh_protocol_version = 2; |
| 1917 |
|
break; |
| 1918 |
|
} |
| 1919 |
|
|
| 1920 |
|
// authority part までポインタを移動 |
| 1921 |
|
p += 3; |
| 1922 |
|
|
| 1923 |
|
// path part を切り捨てる |
| 1924 |
|
if ((p2 = _mbschr(p, '/')) != NULL) { |
| 1925 |
|
*p2 = 0; |
| 1926 |
|
} |
| 1927 |
|
|
| 1928 |
|
// '@'があった場合、それより前はユーザ情報 |
| 1929 |
|
if ((p2 = _mbschr(p, '@')) != NULL) { |
| 1930 |
|
*p2 = 0; |
| 1931 |
|
// ':'以降はパスワード |
| 1932 |
|
if ((p3 = _mbschr(p, ':')) != NULL) { |
| 1933 |
|
*p3 = 0; |
| 1934 |
|
percent_decode(pvar->ssh2_password, sizeof(pvar->ssh2_password), p3 + 1); |
| 1935 |
|
} |
| 1936 |
|
percent_decode(pvar->ssh2_username, sizeof(pvar->ssh2_username), p); |
| 1937 |
|
// p が host part の先頭('@'の次の文字)を差すようにする |
| 1938 |
|
p = p2 + 1; |
| 1939 |
|
} |
| 1940 |
|
|
| 1941 |
|
// host part を option の先頭に移動して、scheme part を潰す |
| 1942 |
|
// port指定が無かった時にport番号を足すための領域確保の意味もある |
| 1943 |
|
hostlen = strlen(p); |
| 1944 |
|
memmove_s(option, optlen, p, hostlen); |
| 1945 |
|
option[hostlen] = 0; |
| 1946 |
|
|
| 1947 |
|
// ポート指定が無い時は":22"を足す |
| 1948 |
|
#ifndef NO_INET6 |
| 1949 |
|
if (option[0] == '[' && option[hostlen-1] == ']' || // IPv6 raw address without port |
| 1950 |
|
option[0] != '[' && _mbschr(option, ':') == NULL) { // hostname or IPv4 raw address without port |
| 1951 |
|
#else |
| 1952 |
|
if (_mbschr(option, ':') == NULL) { |
| 1953 |
|
#endif /* NO_INET6 */ |
| 1954 |
|
memcpy_s(option+hostlen, optlen-hostlen, ":22", 3); |
| 1955 |
|
hostlen += 3; |
| 1956 |
|
} |
| 1957 |
|
|
| 1958 |
|
// ポート指定より後をすべてスペースで潰す |
| 1959 |
|
memset(option+hostlen, ' ', optlen-hostlen); |
| 1960 |
|
|
| 1961 |
|
pvar->settings.Enabled = 1; |
| 1962 |
|
|
| 1963 |
|
action = OPTION_REPLACE; |
| 1964 |
|
} |
| 1965 |
|
else if (_mbschr(option, '@') != NULL) { |
| 1966 |
|
// |
| 1967 |
|
// user@host 形式のサポート |
| 1968 |
|
// 取り合えずsshでのみサポートの為、ユーザ名はttssh内で潰す。 |
| 1969 |
|
// (ssh接続以外 -- ttsshには関係ない場合でも) |
| 1970 |
|
// 将来的にtelnet authentication optionをサポートした時は |
| 1971 |
|
// Tera Term本体で処理するようにする予定。 |
| 1972 |
|
// |
| 1973 |
|
char *p; |
| 1974 |
|
p = _mbschr(option, '@'); |
| 1975 |
|
*p = 0; |
| 1976 |
|
|
| 1977 |
|
strncpy_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), option, _TRUNCATE); |
| 1978 |
|
|
| 1979 |
|
// ユーザ名部分をスペースで潰す。 |
| 1980 |
|
// 後続のTTXやTera Term本体で解釈する時にはスペースを読み飛ばすので、 |
| 1981 |
|
// ホスト名を先頭に詰める必要は無い。 |
| 1982 |
|
memset(option, ' ', p-option+1); |
| 1983 |
|
|
| 1984 |
|
action = OPTION_REPLACE; |
| 1985 |
|
} |
| 1986 |
|
|
| 1987 |
|
|
| 1988 |
|
switch (action) { |
| 1989 |
|
case OPTION_CLEAR: |
| 1990 |
|
memset(cur, ' ', next-cur); |
| 1991 |
|
break; |
| 1992 |
|
case OPTION_REPLACE: |
| 1993 |
|
memset(cur, ' ', next-cur); |
| 1994 |
|
memcpy(cur+1, option, strlen(option)); |
| 1995 |
|
break; |
| 1996 |
|
} |
| 1997 |
|
|
| 1998 |
|
cur = next; |
| 1999 |
|
} |
| 2000 |
|
|
| 2001 |
|
free(option); |
| 2002 |
|
|
| 2003 |
|
FWDUI_load_settings(pvar); |
| 2004 |
|
|
| 2005 |
|
(pvar->ParseParam) (param, ts, DDETopic); |
| 2006 |
|
} |
| 2007 |
|
#else |
| 2008 |
/* returns 1 if the option text must be deleted */ |
/* returns 1 if the option text must be deleted */ |
| 2009 |
static int parse_option(PTInstVar pvar, char FAR * option) |
static int parse_option(PTInstVar pvar, char FAR * option) |
| 2010 |
{ |
{ |
| 2419 |
(pvar->ParseParam) (param, ts, DDETopic); |
(pvar->ParseParam) (param, ts, DDETopic); |
| 2420 |
|
|
| 2421 |
} |
} |
| 2422 |
|
#endif |
| 2423 |
|
|
| 2424 |
static void PASCAL FAR TTXGetSetupHooks(TTXSetupHooks FAR * hooks) |
static void PASCAL FAR TTXGetSetupHooks(TTXSetupHooks FAR * hooks) |
| 2425 |
{ |
{ |
| 5558 |
|
|
| 5559 |
static void dquote_string(char *str, char *dst, int dst_len) |
static void dquote_string(char *str, char *dst, int dst_len) |
| 5560 |
{ |
{ |
| 5561 |
// ",スペース,^A-^_ が含まれる場合にはクオートする |
// ",スペース,;,^A-^_ が含まれる場合にはクオートする |
| 5562 |
if (strchr(str, '"') != NULL || |
if (strchr(str, '"') != NULL || |
| 5563 |
strchr(str, ' ') != NULL || |
strchr(str, ' ') != NULL || |
| 5564 |
|
strchr(str, ';') != NULL || |
| 5565 |
strchr(str, 0x01) != NULL || |
strchr(str, 0x01) != NULL || |
| 5566 |
strchr(str, 0x02) != NULL || |
strchr(str, 0x02) != NULL || |
| 5567 |
strchr(str, 0x03) != NULL || |
strchr(str, 0x03) != NULL || |