CTRLClient.cpp
上传用户:woshihumen
上传日期:2013-07-18
资源大小:484k
文件大小:12k
源码类别:

Email服务器

开发平台:

Visual C++

  1. /*
  2.  *  XMail by Davide Libenzi ( Intranet and Internet mail server )
  3.  *  Copyright (C) 1999,..,2004  Davide Libenzi
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  *
  19.  *  Davide Libenzi <davidel@xmailserver.org>
  20.  *
  21.  */
  22. #include "SysInclude.h"
  23. #include "SysDep.h"
  24. #include "SvrDefines.h"
  25. #include "BuffSock.h"
  26. #include "MiscUtils.h"
  27. #include "StrUtils.h"
  28. #include "MD5.h"
  29. #include "Errors.h"
  30. #define STD_CTRL_PORT               6017
  31. #define STD_CTRL_TIMEOUT            90
  32. #define CTRL_LISTFOLLOW_RESULT      100
  33. #define CTRL_WAITDATA_RESULT        101
  34. #define CCLN_ERR_BAD_USAGE          (-10000)
  35. ///////////////////////////////////////////////////////////////////////////////
  36. //  Needed by library functions ( START )
  37. ///////////////////////////////////////////////////////////////////////////////
  38. bool bServerDebug = false;
  39. int iLogRotateHours = 24;
  40. char *SvrGetLogsDir(char *pszLogsDir, int iMaxPath)
  41. {
  42. SysSNPrintf(pszLogsDir, iMaxPath - 1, ".");
  43. return (pszLogsDir);
  44. }
  45. ///////////////////////////////////////////////////////////////////////////////
  46. //  Needed by library functions ( END )
  47. ///////////////////////////////////////////////////////////////////////////////
  48. int CClnGetResponse(BSOCK_HANDLE hBSock, char *pszError, int iMaxError,
  49.     int *piErrorCode, int iTimeout)
  50. {
  51. char szRespBuffer[2048] = "";
  52. if (BSckGetString(hBSock, szRespBuffer, sizeof(szRespBuffer) - 1, iTimeout) == NULL)
  53. return (ErrGetErrorCode());
  54. if ((szRespBuffer[0] != '+') && (szRespBuffer[0] != '-')) {
  55. ErrSetErrorCode(ERR_CCLN_INVALID_RESPONSE, szRespBuffer);
  56. return (ERR_CCLN_INVALID_RESPONSE);
  57. }
  58. char *pszToken = szRespBuffer + 1;
  59. if (piErrorCode != NULL)
  60. *piErrorCode = atoi(pszToken) * ((szRespBuffer[0] == '-') ? -1 : +1);
  61. for (; isdigit(*pszToken); pszToken++);
  62. if (*pszToken != ' ') {
  63. ErrSetErrorCode(ERR_CCLN_INVALID_RESPONSE, szRespBuffer);
  64. return (ERR_CCLN_INVALID_RESPONSE);
  65. }
  66. for (; *pszToken == ' '; pszToken++);
  67. if (pszError != NULL) {
  68. strncpy(pszError, pszToken, iMaxError);
  69. pszError[iMaxError - 1] = '';
  70. }
  71. return (0);
  72. }
  73. int CClnRecvTextFile(const char *pszFileName, BSOCK_HANDLE hBSock, int iTimeout)
  74. {
  75. bool bCloseFile = false;
  76. FILE *pFile = stdout;
  77. if (pszFileName != NULL) {
  78. if ((pFile = fopen(pszFileName, "wt")) == NULL) {
  79. ErrSetErrorCode(ERR_FILE_CREATE, pszFileName);
  80. return (ERR_FILE_CREATE);
  81. }
  82. bCloseFile = true;
  83. }
  84. char szBuffer[2048] = "";
  85. while (BSckGetString(hBSock, szBuffer, sizeof(szBuffer) - 1, iTimeout) != NULL) {
  86. if (strcmp(szBuffer, ".") == 0)
  87. break;
  88. if (szBuffer[0] == '.')
  89. fprintf(pFile, "%sn", szBuffer + 1);
  90. else
  91. fprintf(pFile, "%sn", szBuffer);
  92. }
  93. if (bCloseFile)
  94. fclose(pFile);
  95. return (0);
  96. }
  97. int CClnSendTextFile(const char *pszFileName, BSOCK_HANDLE hBSock, int iTimeout)
  98. {
  99. bool bCloseFile = false;
  100. FILE *pFile = stdin;
  101. if (pszFileName != NULL) {
  102. if ((pFile = fopen(pszFileName, "rt")) == NULL) {
  103. ErrSetErrorCode(ERR_FILE_OPEN, pszFileName);
  104. return (ERR_FILE_OPEN);
  105. }
  106. bCloseFile = true;
  107. }
  108. char szBuffer[2048] = "";
  109. while (MscFGets(szBuffer, sizeof(szBuffer) - 1, pFile) != NULL) {
  110. if (szBuffer[0] == '.')
  111. for (int ii = strlen(szBuffer); ii >= 0; ii--)
  112. szBuffer[ii + 1] = szBuffer[ii];
  113. if (BSckSendString(hBSock, szBuffer, iTimeout) <= 0) {
  114. fclose(pFile);
  115. return (ErrGetErrorCode());
  116. }
  117. }
  118. if (bCloseFile)
  119. fclose(pFile);
  120. return (BSckSendString(hBSock, ".", iTimeout));
  121. }
  122. int CClnSubmitCommand(BSOCK_HANDLE hBSock, char const *pszCommand,
  123.       char *pszError, int iMaxError, char const *pszIOFile, int iTimeout)
  124. {
  125. if (BSckSendString(hBSock, pszCommand, iTimeout) < 0)
  126. return (ErrGetErrorCode());
  127. int iErrorCode = 0;
  128. if (CClnGetResponse(hBSock, pszError, iMaxError, &iErrorCode, iTimeout) < 0)
  129. return (ErrGetErrorCode());
  130. if (iErrorCode < 0) {
  131. ErrSetErrorCode(ERR_CCLN_ERROR_RESPONSE, pszError);
  132. return (ERR_CCLN_ERROR_RESPONSE);
  133. }
  134. if (iErrorCode == CTRL_LISTFOLLOW_RESULT) {
  135. if (CClnRecvTextFile(pszIOFile, hBSock, iTimeout) < 0)
  136. return (ErrGetErrorCode());
  137. } else if (iErrorCode == CTRL_WAITDATA_RESULT) {
  138. if (CClnSendTextFile(pszIOFile, hBSock, iTimeout) < 0)
  139. return (ErrGetErrorCode());
  140. if (CClnGetResponse(hBSock, pszError, iMaxError, &iErrorCode, iTimeout) < 0)
  141. return (ErrGetErrorCode());
  142. }
  143. return (0);
  144. }
  145. BSOCK_HANDLE CClnConnectServer(char const *pszServer, int iPortNo,
  146.        char const *pszUsername, char const *pszPassword,
  147.        bool bUseMD5Auth, int iTimeout)
  148. {
  149. ///////////////////////////////////////////////////////////////////////////////
  150. //  Get server address
  151. ///////////////////////////////////////////////////////////////////////////////
  152. SYS_INET_ADDR SvrAddr;
  153. if (MscGetServerAddress(pszServer, SvrAddr, iPortNo) < 0)
  154. return (INVALID_BSOCK_HANDLE);
  155. ///////////////////////////////////////////////////////////////////////////////
  156. //  Try connect to server
  157. ///////////////////////////////////////////////////////////////////////////////
  158. SYS_SOCKET SockFD = SysCreateSocket(AF_INET, SOCK_STREAM, 0);
  159. if (SockFD == SYS_INVALID_SOCKET)
  160. return (INVALID_BSOCK_HANDLE);
  161. if (SysConnect(SockFD, &SvrAddr, sizeof(SvrAddr), iTimeout) < 0) {
  162. SysCloseSocket(SockFD);
  163. return (INVALID_BSOCK_HANDLE);
  164. }
  165. BSOCK_HANDLE hBSock = BSckAttach(SockFD);
  166. if (hBSock == INVALID_BSOCK_HANDLE) {
  167. SysCloseSocket(SockFD);
  168. return (INVALID_BSOCK_HANDLE);
  169. }
  170. ///////////////////////////////////////////////////////////////////////////////
  171. //  Read welcome message
  172. ///////////////////////////////////////////////////////////////////////////////
  173. int iErrorCode = 0;
  174. char szRTXBuffer[2048] = "";
  175. if (CClnGetResponse(hBSock, szRTXBuffer, sizeof(szRTXBuffer), &iErrorCode, iTimeout) < 0) {
  176. BSckDetach(hBSock, 1);
  177. return (INVALID_BSOCK_HANDLE);
  178. }
  179. if (iErrorCode < 0) {
  180. BSckDetach(hBSock, 1);
  181. ErrSetErrorCode(ERR_CCLN_ERROR_RESPONSE, szRTXBuffer);
  182. return (INVALID_BSOCK_HANDLE);
  183. }
  184. ///////////////////////////////////////////////////////////////////////////////
  185. //  Prepare login
  186. ///////////////////////////////////////////////////////////////////////////////
  187. char szTimeStamp[256] = "";
  188. if (!bUseMD5Auth ||
  189.     (MscExtractServerTimeStamp(szRTXBuffer, szTimeStamp, sizeof(szTimeStamp)) == NULL))
  190. sprintf(szRTXBuffer, ""%s"t"%s"", pszUsername, pszPassword);
  191. else {
  192. ///////////////////////////////////////////////////////////////////////////////
  193. //  Perform MD5 authentication
  194. ///////////////////////////////////////////////////////////////////////////////
  195. char *pszHash = StrSprint("%s%s", szTimeStamp, pszPassword);
  196. if (pszHash == NULL) {
  197. BSckDetach(hBSock, 1);
  198. return (INVALID_BSOCK_HANDLE);
  199. }
  200. char szMD5[128] = "";
  201. do_md5_string(pszHash, strlen(pszHash), szMD5);
  202. SysFree(pszHash);
  203. ///////////////////////////////////////////////////////////////////////////////
  204. //  Add a  #  char in head of password field
  205. ///////////////////////////////////////////////////////////////////////////////
  206. sprintf(szRTXBuffer, ""%s"t"#%s"", pszUsername, szMD5);
  207. }
  208. ///////////////////////////////////////////////////////////////////////////////
  209. //  Send login
  210. ///////////////////////////////////////////////////////////////////////////////
  211. if (BSckSendString(hBSock, szRTXBuffer, iTimeout) < 0) {
  212. BSckDetach(hBSock, 1);
  213. return (INVALID_BSOCK_HANDLE);
  214. }
  215. if (CClnGetResponse(hBSock, szRTXBuffer, sizeof(szRTXBuffer), &iErrorCode, iTimeout) < 0) {
  216. BSckDetach(hBSock, 1);
  217. return (INVALID_BSOCK_HANDLE);
  218. }
  219. if (iErrorCode < 0) {
  220. BSckDetach(hBSock, 1);
  221. ErrSetErrorCode(ERR_CCLN_ERROR_RESPONSE, szRTXBuffer);
  222. return (INVALID_BSOCK_HANDLE);
  223. }
  224. return (hBSock);
  225. }
  226. int CClnQuitConnection(BSOCK_HANDLE hBSock, int iTimeout)
  227. {
  228. CClnSubmitCommand(hBSock, ""quit"", NULL, 0, NULL, iTimeout);
  229. BSckDetach(hBSock, 1);
  230. return (0);
  231. }
  232. int CClnLogError(void)
  233. {
  234. char *pszError = ErrGetErrorStringInfo(ErrGetErrorCode());
  235. if (pszError == NULL)
  236. return (ErrGetErrorCode());
  237. fprintf(stderr, "%sn", pszError);
  238. SysFree(pszError);
  239. return (0);
  240. }
  241. void CClnShowUsage(char const *pszProgName)
  242. {
  243. fprintf(stderr,
  244. "use :  %s  [-snuptfc]  ...n"
  245. "options :n"
  246. "       -s server        = set server addressn"
  247. "       -n port          = set server port [%d]n"
  248. "       -u user          = set usernamen"
  249. "       -p pass          = set passwordn"
  250. "       -t timeout       = set timeout [%d]n"
  251. "       -f filename      = set I/O filename [stdin/stdout]n"
  252. "       -c               = disable MD5 authenticationn",
  253. pszProgName, STD_CTRL_PORT, STD_CTRL_TIMEOUT);
  254. }
  255. int CClnExec(int iArgCount, char *pszArgs[])
  256. {
  257. int ii;
  258. int iPortNo = STD_CTRL_PORT;
  259. int iTimeout = STD_CTRL_TIMEOUT;
  260. bool bUseMD5Auth = true;
  261. char szServer[MAX_HOST_NAME] = "";
  262. char szUsername[256] = "";
  263. char szPassword[256] = "";
  264. char szIOFile[SYS_MAX_PATH] = "";
  265. for (ii = 1; ii < iArgCount; ii++) {
  266. if (pszArgs[ii][0] != '-')
  267. break;
  268. switch (pszArgs[ii][1]) {
  269. case ('s'):
  270. if (++ii < iArgCount)
  271. StrSNCpy(szServer, pszArgs[ii]);
  272. break;
  273. case ('n'):
  274. if (++ii < iArgCount)
  275. iPortNo = atoi(pszArgs[ii]);
  276. break;
  277. case ('u'):
  278. if (++ii < iArgCount)
  279. StrSNCpy(szUsername, pszArgs[ii]);
  280. break;
  281. case ('p'):
  282. if (++ii < iArgCount)
  283. StrSNCpy(szPassword, pszArgs[ii]);
  284. break;
  285. case ('t'):
  286. if (++ii < iArgCount)
  287. iTimeout = atoi(pszArgs[ii]);
  288. break;
  289. case ('f'):
  290. if (++ii < iArgCount)
  291. StrSNCpy(szIOFile, pszArgs[ii]);
  292. break;
  293. case ('c'):
  294. bUseMD5Auth = false;
  295. break;
  296. default:
  297. return (CCLN_ERR_BAD_USAGE);
  298. }
  299. }
  300. if ((strlen(szServer) == 0) || (strlen(szUsername) == 0) ||
  301.     (strlen(szPassword) == 0) || (ii == iArgCount))
  302. return (CCLN_ERR_BAD_USAGE);
  303. int iFirstParam = ii;
  304. int iCmdLength = 0;
  305. for (; ii < iArgCount; ii++)
  306. iCmdLength += strlen(pszArgs[ii]) + 4;
  307. char *pszCommand = (char *) SysAlloc(iCmdLength + 1);
  308. if (pszCommand == NULL)
  309. return (ErrGetErrorCode());
  310. for (ii = iFirstParam; ii < iArgCount; ii++) {
  311. if (ii == iFirstParam)
  312. sprintf(pszCommand, ""%s"", pszArgs[ii]);
  313. else
  314. sprintf(pszCommand + strlen(pszCommand), "t"%s"", pszArgs[ii]);
  315. }
  316. BSOCK_HANDLE hBSock = CClnConnectServer(szServer, iPortNo, szUsername, szPassword,
  317. bUseMD5Auth, iTimeout);
  318. if (hBSock == INVALID_BSOCK_HANDLE) {
  319. ErrorPush();
  320. SysFree(pszCommand);
  321. return (ErrorPop());
  322. }
  323. char szRTXBuffer[2048] = "";
  324. if (CClnSubmitCommand(hBSock, pszCommand, szRTXBuffer, sizeof(szRTXBuffer),
  325.       (strlen(szIOFile) != 0) ? szIOFile : NULL, iTimeout) < 0) {
  326. ErrorPush();
  327. CClnQuitConnection(hBSock, iTimeout);
  328. SysFree(pszCommand);
  329. return (ErrorPop());
  330. }
  331. SysFree(pszCommand);
  332. CClnQuitConnection(hBSock, iTimeout);
  333. return (0);
  334. }
  335. #ifndef __CTRLCLNT_LIBRARY__
  336. int main(int iArgCount, char *pszArgs[])
  337. {
  338. if (SysInitLibrary() < 0) {
  339. CClnLogError();
  340. return (1);
  341. }
  342. int iExecResult = CClnExec(iArgCount, pszArgs);
  343. if (iExecResult == CCLN_ERR_BAD_USAGE) {
  344. CClnShowUsage(pszArgs[0]);
  345. SysCleanupLibrary();
  346. return (2);
  347. } else if (iExecResult < 0) {
  348. CClnLogError();
  349. SysCleanupLibrary();
  350. return (3);
  351. }
  352. SysCleanupLibrary();
  353. return (0);
  354. }
  355. #endif // #ifndef __CTRLCLNT_LIBRARY__