You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

local_scan.c 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. /*
  2. This program is RSPAMD agent for use with
  3. exim (http://www.exim.org) MTA by its local_scan feature.
  4. To enable exim local scan please copy this file to exim source tree
  5. Local/local_scan.c, edit Local/Makefile to add
  6. LOCAL_SCAN_SOURCE=Local/local_scan.c
  7. LOCAL_SCAN_HAS_OPTIONS=yes
  8. and compile exim.
  9. Comment out RSPAM_UNIXSOCKET definition below if you have remote RSPAMD
  10. daemon
  11. AND
  12. use Exim parameters daemonIP and daemonPort to configure remote
  13. RSPAMD daemon.
  14. For exim compilation with local scan feature details please visit
  15. http://www.exim.org/exim-html-4.50/doc/html/spec_toc.html#TOC333
  16. For RSPAMD details please visit
  17. http://rspamd.sourceforge.net
  18. */
  19. /* Comment out the row below to use socket type AF_INET
  20. to connect RSPAMD daemon */
  21. //#define RSPAM_UNIXSOCKET
  22. #include <stdio.h>
  23. #include <errno.h>
  24. #include <fcntl.h>
  25. #include <string.h>
  26. #include <sys/types.h>
  27. #include <sys/socket.h>
  28. #include <sys/un.h>
  29. #include <netinet/in.h>
  30. #include <stdlib.h>
  31. #include "local_scan.h"
  32. extern uschar *sender_helo_name;
  33. extern int message_size;
  34. #define READ_FAIL(x) ((x) < 0)
  35. #define RSPAMD_FAILURE_HDR "X-Spam-Flag"
  36. #define RSPAMD_SCORE_HDR "X-Spam-Status"
  37. #define REJECT_ON_ERROR 0
  38. static int _OK = 0;
  39. static int ERR_WRITE = 53;
  40. static int ERR_READ = 54;
  41. static int MAX_FAILS_C = 256;
  42. static int MAX_PATH = 256;
  43. static int MAX_SIZE_FILE = 64*1024;
  44. static uschar *daemonIP = US"127.0.0.1";
  45. static int daemonPort = 11333;
  46. static uschar *temp_dir = US"/var/tmp";
  47. static uschar *socket_name = US"/var/run/rspamd.sock";
  48. static int strange = 0;
  49. optionlist local_scan_options[] =
  50. {
  51. {"rspam_ip", opt_stringptr, &daemonIP},
  52. {"rspam_port", opt_int, &daemonPort},
  53. {"rspam_tmp", opt_stringptr, &temp_dir},
  54. {"rspam_sock", opt_stringptr, &socket_name},
  55. };
  56. int local_scan_options_count = sizeof (local_scan_options) / sizeof (optionlist);
  57. typedef int socket_t;
  58. static socket_t sock = -1;
  59. int iFdInp;
  60. struct sockaddr_un ssun;
  61. struct sockaddr_in ssin;
  62. static int mOpenTmp (char *pszDir, char *pszPrefix, char *pszPath)
  63. {
  64. int iLen;
  65. int iFd = -1;
  66. char *pszSep = "";
  67. iLen = (int)strlen(pszDir);
  68. if (iLen > MAX_PATH)
  69. return -1;
  70. if (pszDir[iLen - 1] != '/')
  71. pszSep = "/";
  72. sprintf (pszPath, "%s%s%sXXXXXX", pszDir, pszSep, pszPrefix);
  73. iFd = mkstemp (pszPath);
  74. if (iFd < 0)
  75. log_write (0, LOG_MAIN, "rspam-exim: Temp file create error %d", errno);
  76. return iFd;
  77. }
  78. static int ReadFd (int iFdMsg, int fd)
  79. {
  80. char psMsg [MAX_SIZE_FILE]; /* max size SO can swallow */
  81. int iLen, result = _OK;
  82. if ((iLen = read (fd, psMsg, sizeof (psMsg))) > 0)
  83. {
  84. if (write (iFdMsg, psMsg, (unsigned int) iLen) != iLen)
  85. result = ERR_WRITE;
  86. }
  87. else
  88. result = ERR_READ;
  89. close (iFdMsg);
  90. return result;
  91. }
  92. void CleanupInp (char *sName)
  93. {
  94. if (sName) unlink (sName);
  95. close (iFdInp);
  96. return;
  97. }
  98. int FakeSMTPCommand (socket_t sock,
  99. char *command,
  100. char *value,
  101. char *sName,
  102. int Cleanup,
  103. int wa)
  104. {
  105. char sCommand[1024];
  106. char answ [3];
  107. int Len;
  108. sprintf (sCommand, "%s %s\r\n", command, value);
  109. if (send (sock, sCommand, strlen (sCommand), 0) != (int) strlen (sCommand))
  110. {
  111. log_write (0, LOG_MAIN, "rspam-exim: socket sending '%s' error %d", sCommand, errno);
  112. if (Cleanup)
  113. CleanupInp (sName);
  114. return ERR_WRITE;
  115. }
  116. if(wa) {
  117. memset (answ, '\0', sizeof (answ));
  118. Len = read (sock, answ, sizeof (answ));
  119. if (READ_FAIL (Len))
  120. {
  121. log_write (0, LOG_MAIN, "rspam-exim: read() error %d, len=%d", errno, Len);
  122. if (Cleanup)
  123. CleanupInp (sName);
  124. return ERR_WRITE;
  125. }
  126. if (strncmp (answ, "OK", 2) != 0)
  127. {
  128. log_write (0, LOG_MAIN, "rspam-exim: server did not confirm, answ=%s", answ);
  129. if (Cleanup)
  130. CleanupInp (sName);
  131. return ERR_WRITE; /* Cannot read message error code */
  132. }
  133. }
  134. return OK;
  135. }
  136. static int written (socket_t fd, const char *vptr, int n)
  137. {
  138. size_t nleft;
  139. int nwritten;
  140. const char *ptr;
  141. ptr = vptr;
  142. nleft = n;
  143. while (nleft > 0)
  144. {
  145. if ((nwritten = send (fd, ptr, nleft, 0)) <= 0)
  146. {
  147. if (errno == EINTR)
  148. nwritten = 0;
  149. else
  150. return (-1);
  151. }
  152. nleft -= nwritten;
  153. ptr += nwritten;
  154. }
  155. return (n);
  156. }
  157. static int SendEnvelope (char *sFile)
  158. {
  159. int i;
  160. char str [256], *rh;
  161. void *psBuf;
  162. int fd, bytesRead;
  163. if(message_size > MAX_SIZE_FILE) {
  164. log_write (0, LOG_MAIN, "rspam-exim: file %s is great %d bytes", sFile, MAX_SIZE_FILE);
  165. return ERR_WRITE;
  166. }
  167. /* send greeting */
  168. // if(FakeSMTPCommand(sock, "PROCESS", "RSPAMC/1.0", sFile, 1, 0) != _OK)
  169. // return ERR_WRITE;
  170. if(FakeSMTPCommand(sock, "SYMBOLS", "RSPAMC/1.1", sFile, 1, 0) != _OK)
  171. // if(FakeSMTPCommand(sock, "CHECK", "RSPAMC/1.0", sFile, 1, 0) != _OK)
  172. return ERR_WRITE;
  173. /* sender IP */
  174. if (FakeSMTPCommand (sock, "IP:", sender_host_address, sFile, 1, 0) != _OK)
  175. return ERR_WRITE;
  176. /* mail from */
  177. if (FakeSMTPCommand (sock, "From:",
  178. strlen (sender_address) == 0 ? "MAILER-DAEMON" : (char*) sender_address, sFile, 1, 0) != _OK)
  179. return ERR_WRITE;
  180. /* send helo */
  181. if (FakeSMTPCommand (sock, "Helo:", sender_helo_name, sFile, 1, 0) != _OK)
  182. return ERR_WRITE;
  183. /* send helo */
  184. sprintf(str, "%d", message_size);
  185. if (FakeSMTPCommand (sock, "Content-Length:", str, sFile, 1, 0) != _OK)
  186. return ERR_WRITE;
  187. /* number of recipient */
  188. sprintf(str, "%d", recipients_count);
  189. if (FakeSMTPCommand (sock, "Recipient-Number:", str, sFile, 1, 0) != _OK)
  190. return ERR_WRITE;
  191. /* envelope rcpto */
  192. for (i = 0; i < recipients_count; i ++)
  193. {
  194. if (FakeSMTPCommand (sock, "Rcpt:", recipients_list[i].address, sFile, 1, 0) != _OK)
  195. return ERR_WRITE;
  196. }
  197. psBuf = store_get (MAX_SIZE_FILE);
  198. fd = open (sFile, O_RDONLY);
  199. if (fd > 0)
  200. {
  201. bytesRead = read (fd, psBuf, MAX_SIZE_FILE);
  202. close (fd);
  203. if (FakeSMTPCommand (sock, "\r\n", "", sFile, 1, 0) != _OK)
  204. return ERR_WRITE;
  205. if (written (sock, psBuf, bytesRead) != bytesRead)
  206. return ERR_WRITE;
  207. }
  208. else
  209. {
  210. log_write (0, LOG_MAIN, "rspam-exim: file %s open error %d", sFile, errno);
  211. return ERR_WRITE;
  212. }
  213. return _OK;
  214. }
  215. int GetFiles (char *pInpFile, int local_scan_fd)
  216. {
  217. /*
  218. Returns OK if no errors, else error code.
  219. On successful return, pEnvFile points to Envelope file name and
  220. pInpFile points to Message filename
  221. */
  222. int iStatus;
  223. struct header_line *h_line;
  224. iFdInp = mOpenTmp ((char *)temp_dir, "sp-inp", pInpFile);
  225. if (iFdInp == -1)
  226. {
  227. return ERR_WRITE;
  228. }
  229. /* Emit headers */
  230. h_line = header_list;
  231. while (h_line != NULL)
  232. {
  233. if (h_line->type == '*') /* internal header */
  234. {
  235. h_line = h_line->next;
  236. continue;
  237. }
  238. if (write (iFdInp, h_line->text, strlen (h_line->text)) != strlen (h_line->text))
  239. {
  240. CleanupInp ("");
  241. return ERR_WRITE;
  242. }
  243. h_line = h_line->next;
  244. }
  245. if (write (iFdInp, "\n", 1) != 1)
  246. {
  247. CleanupInp ("");
  248. return ERR_WRITE;
  249. }
  250. /* Read msg */
  251. if ((iStatus = ReadFd (iFdInp, local_scan_fd)))
  252. {
  253. return iStatus;
  254. }
  255. /* Return success */
  256. return _OK;
  257. }
  258. int GetAndTransferMessage (int fd, char *sFile)
  259. {
  260. char answ [4];
  261. int iStatus;
  262. int Len, ccnt;
  263. int test;
  264. iStatus = GetFiles ((char *)sFile, fd);
  265. if (iStatus != _OK)
  266. {
  267. log_write (0, LOG_MAIN, "rspam-exim: Error %d getting message", iStatus);
  268. close (sock);
  269. return iStatus;
  270. }
  271. for (ccnt = 0; ccnt <= MAX_FAILS_C; ccnt ++)
  272. {
  273. #ifdef RSPAM_UNIXSOCKET
  274. test = connect (sock, (struct sockaddr *) &ssun, sizeof (struct sockaddr_un)) < 0;
  275. #else
  276. test = connect (sock, (struct sockaddr *) &ssin, sizeof (struct sockaddr_in)) < 0;
  277. #endif
  278. if (test)
  279. {
  280. if (ccnt < MAX_FAILS_C)
  281. usleep (1000);
  282. else
  283. {
  284. close (sock);
  285. #ifdef RSPAM_UNIXSOCKET
  286. log_write (0, LOG_MAIN, "rspam-exim: socket connect to %s failed", (char *)socket_name);
  287. #else
  288. log_write (0, LOG_MAIN, "rspam-exim: socket connect to %s:%u failed", daemonIP, daemonPort);
  289. #endif
  290. return REJECT_ON_ERROR ? LOCAL_SCAN_TEMPREJECT:LOCAL_SCAN_ACCEPT;
  291. }
  292. }
  293. else
  294. break;
  295. }
  296. iStatus = SendEnvelope (sFile);
  297. if (iStatus != _OK)
  298. {
  299. log_write (0, LOG_MAIN, "rspam-exim: error %d sending envelope data", iStatus);
  300. close (sock);
  301. return iStatus;
  302. }
  303. /* fprintf (stderr, "Transmit OK\n"); */
  304. return _OK;
  305. }
  306. void header_del (uschar *hdr)
  307. {
  308. struct header_line *h_line;
  309. h_line = header_list;
  310. while (h_line != NULL)
  311. {
  312. if (h_line->type == '*') /* internal header */
  313. {
  314. h_line = h_line->next;
  315. continue;
  316. }
  317. if (strncasecmp (h_line->text, hdr, strlen(hdr)) == 0)
  318. {
  319. h_line->type = '*';
  320. while (h_line->next &&
  321. (*h_line->next->text == ' ' || *h_line->next->text == '\t'))
  322. {
  323. h_line = h_line->next;
  324. h_line->type = '*';
  325. }
  326. }
  327. h_line = h_line->next;
  328. }
  329. }
  330. void AlterSubject (char *label)
  331. {
  332. struct header_line *h_line;
  333. char *subject, *strP;
  334. h_line = header_list;
  335. while (h_line != NULL)
  336. {
  337. if (h_line->type == '*') /* internal header */
  338. {
  339. h_line = h_line->next;
  340. continue;
  341. }
  342. if (strncasecmp (h_line->text, "Subject", strlen("Subject")) == 0)
  343. {
  344. strP = strchr (h_line->text, ':');
  345. subject = string_copy (++strP);
  346. while (h_line->next &&
  347. (*h_line->next->text == ' ' || *h_line->next->text == '\t'))
  348. {
  349. h_line = h_line->next;
  350. subject = string_sprintf ("%s\n%s", subject, h_line->text);
  351. }
  352. header_del (US "Subject");
  353. break;
  354. }
  355. h_line = h_line->next;
  356. }
  357. header_add (' ', "Subject: %s%s", label, subject ? subject : "");
  358. }
  359. int
  360. io_read(int fd, char *buf, size_t size)
  361. {
  362. int nfd, next = 0, rcount = 15;
  363. size_t len = 0;
  364. fd_set fds;
  365. struct timeval tv;
  366. if((sock < 0) || (buf == NULL))
  367. return -1;
  368. FD_ZERO(&fds);
  369. repeat_read:
  370. tv.tv_sec = 5;
  371. tv.tv_usec = 0;
  372. FD_SET(fd, &fds);
  373. // log_write(0, LOG_MAIN, "rspam-exim: before select");
  374. if((nfd=select(fd+1, &fds, NULL, NULL, &tv)) == -1) {
  375. // log_write(0, LOG_MAIN, "rspam-exim: select error: %s", strerror(errno));
  376. return -1;
  377. }
  378. // log_write(0, LOG_MAIN, "rspam-exim: select return %d fds, rcount %d, next %d", nfd, rcount, next);
  379. if((nfd>0) && (FD_ISSET(fd, &fds))) {
  380. next += len = read(fd, buf + next, size - next);
  381. // log_write(0, LOG_MAIN, "rspam-exim: read %d bytes", len);
  382. // if(next<size)
  383. // goto repeat_read;
  384. }
  385. rcount--;
  386. if(rcount>0)
  387. goto repeat_read;
  388. return next;
  389. }
  390. int WaitForScanResult (uschar **resStr)
  391. {
  392. int Len, i;
  393. int rej = 0, result = LOCAL_SCAN_ACCEPT, answer_size, spm = 0, code = 0, ns = 0, smb = 0, urf = 0;
  394. char *strP, *tok, *tmp;
  395. char *hdr = NULL, *hdrv = NULL, *spmStr = NULL, *symbols=NULL, *urls=NULL;
  396. char answ [4096], state[6], metric[128], back;
  397. float sm=0, smd=0, smr=0;
  398. memset (answ, '\0', sizeof (answ));
  399. // log_write(0, LOG_MAIN, "rspam-exim: before read from %d", sock);
  400. // Len = read (sock, answ, sizeof (answ) - 1);
  401. Len = io_read(sock, answ, sizeof (answ) - 1);
  402. log_write(0, LOG_MAIN, "rspam-exim: read %d bytes", Len);
  403. if (strncmp (answ, "RSPAMD/1.1 ", 11) == 0)
  404. {
  405. strP = (char *)answ;
  406. for (tok = strtok (strP, "\n"); tok; tok = strtok (NULL, "\n"))
  407. {
  408. // log_write(0, LOG_MAIN, "rspam-exim: process line '%s'", tok);
  409. if (strncmp (tok, "RSPAMD/1.1 ", 11) == 0)
  410. {
  411. if (sscanf (tok, "%*s %d %s", &code, state) == 2)
  412. {
  413. // log_write(0, LOG_MAIN, "rspam-exim: daemon reports code %d %s", code, state);
  414. if ((code == 0) && (strcmp(state,"OK")==0)) {
  415. header_del ((uschar *) RSPAMD_FAILURE_HDR);
  416. header_add (' ', "%s: SKIP\n", RSPAMD_FAILURE_HDR);
  417. strange = 1;
  418. continue;
  419. } else {
  420. header_del ((uschar *) RSPAMD_FAILURE_HDR);
  421. header_add (' ', "%s: SKIP\n", RSPAMD_FAILURE_HDR);
  422. log_write(0, LOG_MAIN, "rspam-exim: daemon reports code %d %s", code, state);
  423. return LOCAL_SCAN_ACCEPT;
  424. }
  425. }
  426. continue;
  427. }
  428. /* Metric: default; False; 6.00 / 10.00 */
  429. /* Process metric */
  430. if (strncmp (tok, "Metric:", 7) == 0)
  431. {
  432. tmp = tok;
  433. while( (*tmp++) &&
  434. ((*tmp!='\r') || (*tmp!='\n'))
  435. );
  436. back = *tmp;
  437. *tmp = '\0';
  438. if (sscanf (tok, "Metric: %[^';']; %[^';']; %f / %f / %f", metric, state, &sm, &smd, &smr) == 5) {
  439. log_write(0, LOG_MAIN, "rspam-exim: metric: %s; %s; %f / %f / %f", metric, state, sm, smd, smr );
  440. if(strcasecmp(state,"true")==0) {
  441. header_del ((uschar *) RSPAMD_FAILURE_HDR);
  442. header_add (' ', "%s: %s\n", RSPAMD_FAILURE_HDR, "Yes");
  443. } else if(strcasecmp(state,"skip")==0) {
  444. header_del ((uschar *) RSPAMD_FAILURE_HDR);
  445. header_add (' ', "%s: %s\n", RSPAMD_FAILURE_HDR, "Skip");
  446. } else {
  447. header_del ((uschar *) RSPAMD_FAILURE_HDR);
  448. header_add (' ', "%s: %s\n", RSPAMD_FAILURE_HDR, "No");
  449. }
  450. header_del ((uschar *) RSPAMD_SCORE_HDR);
  451. header_add (' ', "%s: %.2f / %.2f / %.2f\n", RSPAMD_SCORE_HDR, sm, smd, smr);
  452. strange = 0;
  453. }
  454. *tmp = back;
  455. continue;
  456. }
  457. if (strncmp (tok, "Symbol:", 7) == 0)
  458. {
  459. tmp = tok;
  460. while( (*tmp++) &&
  461. ((*tmp!='\r') || (*tmp!='\n'))
  462. );
  463. back = *tmp;
  464. *tmp = '\0';
  465. if(smb>0) {
  466. tok += 7;
  467. while(*tok && isspace(*tok)) tok++;
  468. if(strlen(tok)>0) {
  469. symbols = string_sprintf ("%s\n %s", symbols, tok);
  470. }
  471. } else {
  472. tok += 7;
  473. while(*tok && isspace(*tok)) tok++;
  474. symbols = string_copy (tok);
  475. }
  476. smb = 1;
  477. *tmp = back;
  478. continue;
  479. }
  480. if (strncmp (tok, "Urls:", 5) == 0)
  481. {
  482. tmp = tok;
  483. while( (*tmp++) &&
  484. ((*tmp!='\r') || (*tmp!='\n'))
  485. );
  486. back = *tmp;
  487. *tmp = '\0';
  488. if(urf>0) {
  489. tok[0] = tok[1]= tok[2]= tok[3]= tok[4] = ' ';
  490. urls = string_sprintf ("%s\n%s", urls, tok+3);
  491. } else {
  492. tok += 5;
  493. while(*tok && isspace(*tok)) tok++;
  494. urls = string_copy (tok);
  495. }
  496. urf = 1;
  497. *tmp = back;
  498. continue;
  499. }
  500. }
  501. /* do not forget the symbols */
  502. if (symbols != NULL && strlen(symbols))
  503. {
  504. i = 0;
  505. tmp = tok = string_copy(symbols);
  506. header_del ((uschar *) "X-Spam-Sybmols");
  507. header_add (' ', "%s: %s\n", "X-Spam-Sybmols", symbols);
  508. while(*tmp!='\0') {
  509. if(*tmp == '\r')
  510. *tmp = ' ';
  511. if(*tmp == '\n')
  512. *tmp = ',';
  513. tmp++;
  514. }
  515. *tmp = '\0';
  516. log_write(0, LOG_MAIN, "rspam-exim: symbols: %s", tok);
  517. }
  518. /* do not forget the urls */
  519. if (urls != NULL && strlen(urls))
  520. {
  521. log_write(0, LOG_MAIN, "rspam-exim: urls: %s", urls);
  522. header_del ((uschar *) "X-Spam-Urls");
  523. header_add (' ', "%s: %s\n", "X-Spam-Urls", urls);
  524. }
  525. log_write (0, LOG_MAIN, "rspam-exim: For message from %s will return %s, mailfrom: <%s>, rcpto: <%s>", sender_host_address, rej == 2 ? "DISCARD" : rej == 1 ? "REJECT" : "ACCEPT", sender_address, recipients_list[0].address);
  526. }
  527. else
  528. {
  529. result = LOCAL_SCAN_ACCEPT;
  530. log_write(0, LOG_MAIN, "rspam-exim: wrong signature in answer: %s", answ);
  531. }
  532. if((sm>0) && (smr>0) && (sm>=smr)) {
  533. result = LOCAL_SCAN_REJECT;
  534. }
  535. return result;
  536. }
  537. int
  538. local_scan(int fd, uschar **return_text)
  539. {
  540. int retval = _OK;
  541. char sFileInp [MAX_PATH + 81];
  542. /* Socket stuff */
  543. strange = 0;
  544. #ifdef RSPAM_UNIXSOCKET
  545. if ((sock = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
  546. {
  547. log_write(0, LOG_MAIN, "rspam-exim: socket() failed");
  548. exit (EXIT_FAILURE);
  549. }
  550. memset (&ssun, '\0', sizeof (struct sockaddr_un));
  551. ssun.sun_family = AF_UNIX;
  552. if (sizeof (socket_name) > sizeof (ssun.sun_path))
  553. {
  554. close (sock);
  555. log_write(0, LOG_MAIN, "rspam-exim: UNIX socket name %s too long", socket_name);
  556. exit (EXIT_FAILURE);
  557. }
  558. strcpy (ssun.sun_path, socket_name);
  559. #else
  560. if ((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
  561. {
  562. log_write(0, LOG_MAIN, "rspam-exim: socket() failed");
  563. exit (EXIT_FAILURE);
  564. }
  565. memset (&ssin, '\0', sizeof (struct sockaddr_in));
  566. ssin.sin_family = AF_INET;
  567. ssin.sin_addr.s_addr = inet_addr (daemonIP);
  568. ssin.sin_port = htons (daemonPort);
  569. #endif
  570. if (GetAndTransferMessage (fd, (char *)sFileInp) != _OK)
  571. {
  572. close (sock);
  573. unlink (sFileInp);
  574. SPOOL_DATA_START_OFFSET;
  575. return REJECT_ON_ERROR ? LOCAL_SCAN_TEMPREJECT:LOCAL_SCAN_ACCEPT;
  576. }
  577. retval = WaitForScanResult (return_text);
  578. if(!strange)
  579. unlink (sFileInp);
  580. close (sock);
  581. SPOOL_DATA_START_OFFSET;
  582. return retval;
  583. }
  584. /* End of local_scan.c */