static const response* init(void) { const char* path; str rule = {0,0,0}; ibuf in; const response* r; if ((path = getenv("MAILRULES")) == 0) return 0; loaded = 1; if (!ibuf_open(&in, path, 0)) return &resp_erropen; while (ibuf_getstr(&in, &rule, LF)) { str_strip(&rule); if (rule.len == 0) continue; if (rule.s[0] == ':') { switch (rule.s[1]) { case 's': current_rules = &sender_rules; break; case 'r': current_rules = &recip_rules; break; default: return &resp_syntax; } } else if ((r = add(rule.s)) != 0) return r; } ibuf_close(&in); str_free(&rule); return 0; }
int vmailmgr_autoconvert(void) { int writefd = -1; ibuf reader; struct cdb_make writer; int error = 0; int readall = 0; int writerr = 0; if ((writefd = path_mktemp(pwfile, &tmppwfile)) != -1) { if (cdb_make_start(&writer, writefd) != 0) error = CVME_IO | CVME_FATAL; else { if (ibuf_open(&reader, pwfile, 0)) { uint32 end; struct stat st; if (fstat(reader.io.fd, &st) == 0 && fchmod(writefd, st.st_mode) == 0 && fchown(writefd, st.st_uid, st.st_gid) == 0 && read_start(&reader, &end)) { while (ibuf_tell(&reader) < end) { if (!read_cdb_pair(&reader, &key, &data)) break; if (str_diff(&key, &virtuser) == 0) if (!convert_data()) { writerr = 1; break; } if (cdb_make_add(&writer, key.s, key.len, data.s, data.len) != 0) { writerr = 1; break; } } readall = ibuf_tell(&reader) == end; } ibuf_close(&reader); } if (cdb_make_finish(&writer) != 0) error |= CVME_FATAL; else if (readall && !writerr) rename(tmppwfile.s, pwfile); } close(writefd); unlink(tmppwfile.s); } return error; }
void imsg_close(struct imsgbuf *ibuf, struct ibuf *msg) { struct imsg_hdr *hdr; hdr = (struct imsg_hdr *)msg->buf; hdr->flags &= ~IMSGF_HASFD; if (msg->fd != -1) hdr->flags |= IMSGF_HASFD; hdr->len = (u_int16_t)msg->wpos; ibuf_close(&ibuf->w, msg); }
static void dump_msg(long num, long bodylines) { ibuf in; static char buf[4096]; int in_header; /* True until a blank line is seen */ int sol; /* True if at start of line */ if (!ibuf_open(&in, msgs[num-1].filename, 0)) return respond("-ERR Could not open that message"); respond(ok); sol = in_header = 1; while (ibuf_read(&in, buf, sizeof buf) || in.count) { const char* ptr = buf; const char* end = buf + in.count; while (ptr < end) { const char* lfptr; if (sol) { if (!in_header) if (--bodylines < 0) break; if (*ptr == '.') obuf_putc(&outbuf, '.'); } if ((lfptr = memchr(ptr, LF, end-ptr)) == 0) { obuf_write(&outbuf, ptr, end-ptr); ptr = end; sol = 0; } else { if (in_header && lfptr == ptr) in_header = 0; obuf_write(&outbuf, ptr, lfptr-ptr); obuf_puts(&outbuf, CRLF); ptr = lfptr + 1; sol = 1; } } } ibuf_close(&in); obuf_puts(&outbuf, CRLF); respond("."); }
int dict_load_list(dict* d, const char* filename, int mustexist, int (*xform)(str*)) { ibuf in; str tmp = {0,0,0}; int result = 1; if (!dict_init(d)) return 0; if (!ibuf_open(&in, filename, 0)) return !mustexist; while (ibuf_getstr(&in, &tmp, '\n')) { str_strip(&tmp); if (tmp.len > 0 && tmp.s[0] != '#') { if (xform != 0) if (!xform(&tmp)) { result = 0; break; } if (!dict_add(d, &tmp, 0)) { result = 0; break; } } } str_free(&tmp); ibuf_close(&in); return result; }
static const response* message_end(int fd) { const char* hostname; const char* tmp; ipv4port cmdport; ipv4addr ips[MAX_IPS]; int ip_count; int i; int offset; int result; struct timeval tv; int sock; unsigned long timeout; unsigned long connect_timeout; unsigned long send_timeout; unsigned long maxsize; ibuf netin; obuf netout; struct stat st; if ((hostname = session_getenv("CLAMAV_HOST")) != 0 || (hostname = session_getenv("CLAMD_HOST")) != 0) { if (fstat(fd, &st) != 0) return &resp_internal; /* For simplicity, this plugin just sends a single chunk, but each * chunk is limited to 2^32 bytes by the protocol. */ if (st.st_size > 0xffffffffLL) { warn1("ClamAV scanning skipped: message larger than chunk size"); return 0; } if ((tmp = session_getenv("CLAMAV_MAXSIZE")) != 0 && (maxsize = strtoul(tmp, (char**)&tmp, 10)) != 0 && *tmp == 0) { if (st.st_size > (ssize_t)maxsize){ warn1("ClamAV scanning skipped: message larger than maximum"); return 0; } } if (((tmp = session_getenv("CLAMAV_PORT")) == 0 && (tmp = session_getenv("CLAMD_PORT")) == 0) || (cmdport = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) cmdport = 3310; if (((tmp = session_getenv("CLAMAV_TIMEOUT")) == 0 && (tmp = session_getenv("CLAMD_TIMEOUT")) == 0) || (timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) timeout = 5000; if ((tmp = session_getenv("CLAMAV_CONNECT_TIMEOUT")) == 0 || (connect_timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) connect_timeout = timeout; if ((tmp = session_getenv("CLAMAV_SEND_TIMEOUT")) == 0 || (send_timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) send_timeout = timeout; if ((ip_count = resolve_ipv4name_n(hostname, ips, MAX_IPS)) <= 0) return &resp_no_hostname; gettimeofday(&tv, 0); offset = (tv.tv_sec ^ tv.tv_usec) % ip_count; for (i = 0; i < ip_count; ++i) { const ipv4addr* addr = &ips[(i + offset) % ip_count]; if (lseek(fd, 0, SEEK_SET) != 0) return &resp_internal; if ((sock = try_connect(addr, cmdport, connect_timeout)) < 0) continue; if (obuf_init(&netout, sock, 0, 0, 0)) { netout.io.timeout = send_timeout; result = obuf_puts(&netout, "nINSTREAM\n") && copystream(fd, st.st_size, &netout) && obuf_close(&netout); obuf_close(&netout); if (result) { if (ibuf_init(&netin, sock, 0, IOBUF_NEEDSCLOSE, 0)) { netin.io.timeout = timeout; result = ibuf_getstr(&netin, &line, LF); ibuf_close(&netin); sock = -1; if (result) { if (memcmp(line.s, "stream: ", 8) == 0) { str_lcut(&line, 8); str_rstrip(&line); if (str_diffs(&line, "OK") == 0) return 0; str_splices(&line, 0, 0, "5.7.0 Virus scan failed: "); resp_virus.message = line.s; return &resp_virus; } } } } } if (sock >= 0) close(sock); } } return &resp_no_scan; }