void report_io_bytes(void) { static str tmp; if (str_copys(&tmp, "bytes in: ") && str_catu(&tmp, inbuf.io.offset) && str_cats(&tmp, " bytes out: ") && str_catu(&tmp, outbuf.io.offset)) msg1(tmp.s); }
static void cmd_stat(void) { if (!str_copys(&tmp, "+OK ") || !str_catu(&tmp, msg_count - del_count) || !str_catc(&tmp, SPACE) || !str_catu(&tmp, msg_bytes - del_bytes)) respond(err_internal); else respond(tmp.s); }
static void cmd_list_one(const str* arg) { long i; if ((i = msgnum(arg)) == 0) return; if (!str_copys(&tmp, "+OK ") || !str_catu(&tmp, i) || !str_catc(&tmp, SPACE) || !str_catu(&tmp, msgs[i-1].size)) respond(err_internal); else respond(tmp.s); }
const char* temppath(const char* prefix, str* path) { struct timeval tv; gettimeofday(&tv, 0); if (!str_copy2s(path, prefix, ".tmp.barch.") || !str_catu(path, pid) || !str_catc(path, '.') || !str_catu(path, tv.tv_sec) || !str_catc(path, '.') || !str_catuw(path, tv.tv_usec, 6, '0')) die_oom(1); return path->s; }
static const response* get_seq(void) { str sql; str_init(&sql); /* do IPv6 differently */ if(strchr(remote_ip, ':')) { if(!str_copy5s(&sql, "INSERT INTO mail SET serial=NULL,mailtime=NULL,server6=INET_PTO6('", local_ip, "'),sourceip6=INET_PTO6('", remote_ip, "')")) return &resp_internal; } else { if(!str_copy5s(&sql, "INSERT INTO mail SET serial=NULL,mailtime=NULL,server=INET_ATON('", local_ip, "'),sourceip=INET_ATON('", remote_ip, "')")) return &resp_internal; } if(!sqlquery(&sql, &sqlseq) || !str_init(&sqlseqstr) || !str_catu(&sqlseqstr, sqlseq)) return &resp_internal; msg2("assigned seq ",sqlseqstr.s); session_setnum("sqlseq", (unsigned long)sqlseq); return 0; }
static const response* message_end(int fd) { struct stat st; char buf[1024]; long rd; char* lf; char* ptr; if (fd >= 0) { /* Log the first two lines of the message, usually a Received: header */ lseek(fd, 0, SEEK_SET); rd = read(fd, buf, sizeof buf - 1); buf[rd] = 0; if ((lf = strchr(buf, LF)) != 0) { str_copyb(&tmp, buf, lf-buf); ptr = lf + 1; if ((lf = strchr(ptr, LF)) != 0) str_catb(&tmp, ptr, lf-ptr); msg1(tmp.s); } fstat(fd, &st); databytes = st.st_size; } str_copys(&tmp, "Received "); str_catu(&tmp, databytes); str_cats(&tmp, " bytes."); resp.message = tmp.s; return &resp; (void)fd; }
/** Create a temporary file. This function creates a temporary file by adding an difficult-to-predict suffix (using the PID and microsecond timestamp) to the given prefix. If this filename does not exist, it is opened in read/write mode. */ int path_mktemp(const char* prefix, str* filename) { struct stat s; static long pid = 0; struct timeval tv; if (pid == 0) pid = getpid(); do { if (!str_copys(filename, prefix)) return -1; if (!str_catc(filename, '.')) return -1; if (!str_catu(filename, pid)) return -1; gettimeofday(&tv, 0); if (!str_catc(filename, '.')) return -1; if (!str_catu(filename, tv.tv_sec)) return -1; if (!str_catc(filename, '.')) return -1; if (!str_catuw(filename, tv.tv_usec, 6, '0')) return -1; } while (lstat(filename->s, &s) != -1); return open(filename->s, O_RDWR | O_EXCL | O_CREAT, 0600); }
int main(int argc, char* argv[]) { static str fdstr; const char* tmp; const char* end; int sock[2]; if (argc < 2) { respond(421, 1, "Configuration error, insufficient paramenters."); return 0; } if ((tmp = getenv("TCPLOCALIP")) == 0 || (end = ipv4_scan(tmp, &ip)) == 0 || *end != 0) { respond(421, 1, "Configuration error, $TCPLOCALIP is not set or is invalid."); return 0; } if ((tmp = getenv("TWOFTPD_BIND_PORT")) != 0) { port = strtoul(tmp, (char**)&end, 10); if (*end != 0) port = 20; } else port = 20; if (!socket_pairdgm(sock)) { respond_syserr(421, "Could not create socket pair."); return 0; } if (!str_catu(&fdstr, sock[0]) || setenv("TWOFTPD_BIND_PORT_FD", fdstr.s, 1) == -1) { respond_syserr(421, "Could not set $TWOFTPD_BIND_PORT_FD."); return 0; } ppid = getpid(); switch (fork()) { case -1: respond_syserr(421, "Could not fork."); break; case 0: close(sock[0]); mainloop(sock[1]); break; default: close(sock[1]); execvp(argv[1], argv+1); respond_syserr(421, "Could not execute command line."); } return 0; }
/* ------------------------------------------------------------------------- */ const char* format_connection(const struct connections_entry* c) { static str s; if (!str_copys(&s, ipv4_format(&c->key.ip))) return 0; if (!str_catc(&s, '/')) return 0; if (!str_catu(&s, c->key.port)) return 0; if (!str_catc(&s, '/')) return 0; if (!str_cat(&s, &c->data.service->key.sender)) return 0; if (!str_catc(&s, '/')) return 0; if (!str_cat(&s, &c->data.service->key.service)) return 0; if (!str_cats(&s, ": ")) return 0; return s.s; }
static void cmd_uidl_one(const str* arg) { long i; if ((i = msgnum(arg)) != 0) { msg* m = &msgs[i-1]; const char* fn = m->filename + 4; if (!str_copys(&tmp, "+OK ") || !str_catu(&tmp, i) || !str_catc(&tmp, SPACE) || !str_catb(&tmp, fn, m->uid_len)) respond(err_internal); else respond(tmp.s); } }
int sendpacket(int fd, const str* s) { const char* ptr; long wr; long len; packet.len = 0; if (!str_catu(&packet, s->len) || !str_catc(&packet, ':') || !str_cat(&packet, s) || !str_catc(&packet, ',')) { errno = ENOMEM; return -1; } len = packet.len; ptr = packet.s; while (len > 0) { if ((wr = write(fd, ptr, len)) <= 0) return wr; len -= wr; ptr += wr; } return packet.len; }