/** * Takes a dvector and implodes it to a string based on a specific * character to delimit by. * Returns a dstrbuf */ dstrbuf * implode(dvector vec, char delim) { dstrbuf *buf = dsbNew(100); size_t veclen = dvLength(vec); uint i=0; for (i=0; i < veclen; i++) { dsbCat(buf, vec[i]); if ((i+1) < veclen) { /* Only append a ',' if we're not at the end. */ dsbCat(buf, &delim); } } return buf; }
/** * will save the sent email if a place is specified in the * configuration file It will append each email to one particular * file called 'email.sent' **/ static int saveSentEmail(dstrbuf *msg) { FILE *save; char *save_file = NULL; dstrbuf *path; save_file = getConfValue("SAVE_SENT_MAIL"); if (!save_file) { return ERROR; } path = expandPath(save_file); dsbCat(path, "/email.sent"); if (!(save = fopen(path->str, "a"))) { warning("Could not open file: %s", path->str); dsbDestroy(path); return ERROR; } fputs(msg->str, save); fflush(save); fclose(save); return SUCCESS; }
/** * Makes a standard plain text message while taking into * account the MIME message types and boundary's needed * if and when a file is attached. **/ static int makeMessage(dstrbuf *in, dstrbuf *out, const char *border, CharSetType charset) { dstrbuf *enc=NULL; if (Mopts.attach) { dsbPrintf(out, "--%s\r\n", border); if (charset == IS_UTF8 || charset == IS_PARTIAL_UTF8) { dsbPrintf(out, "Content-Type: text/plain; charset=utf-8\r\n"); if (IS_PARTIAL_UTF8) { dsbPrintf(out, "Content-Transfer-Encoding: quoted-printable\r\n"); enc = mimeQpEncodeString((u_char *)in->str, true); } else { dsbPrintf(out, "Content-Transfer-Encoding: base64\r\n"); enc = mimeB64EncodeString((u_char *)in->str, in->len, true); } dsbPrintf(out, "Content-Disposition: inline\r\n\r\n"); } else if (Mopts.html) { dsbPrintf(out, "Content-Type: text/html\r\n\r\n"); enc = DSB_NEW; dsbCat(enc, in->str); } else { dsbPrintf(out, "Content-Type: text/plain\r\n\r\n"); enc = DSB_NEW; dsbCat(enc, in->str); } } else { if (charset == IS_UTF8) { enc = mimeB64EncodeString((u_char *)in->str, in->len, true); } else if (charset == IS_PARTIAL_UTF8) { enc = mimeQpEncodeString((u_char *)in->str, true); } else { enc = DSB_NEW; dsbCat(enc, in->str); } } dsbPrintf(out, "%s\r\n", enc->str); if (Mopts.attach) { if (attachFiles(border, out) == ERROR) { return ERROR; } dsbPrintf(out, "\r\n\r\n--%s--\r\n", border); } dsbDestroy(enc); return 0; }
/** * takes a string that is a supposed file path, and * checks for certian wildcards ( like ~ for home directory ) * and resolves to an actual absolute path. **/ dstrbuf * expandPath(const char *path) { struct passwd *pw = NULL; dstrbuf *tmp = DSB_NEW; dstrbuf *ret = DSB_NEW; dsbCopy(tmp, path); if (tmp->len > 0 && tmp->str[0] == '&') { dsbCopy(ret, EMAIL_DIR); } else if (tmp->len > 0 && tmp->str[0] == '~') { if (tmp->str[1] == '/') { pw = getpwuid(getuid()); } else { int pos = strfind(tmp->str, '/'); if (pos >= 0) { char *p = substr(tmp->str, 1, pos-1); if (p) { pw = getpwnam(p); xfree(p); } } if (!pw) { pw = getpwuid(getuid()); } } if (pw) { dsbCopy(ret, pw->pw_dir); } } if (ret->len > 0) { int pos = strfind(tmp->str, '/'); if (pos > 0) { char *p = substr(tmp->str, pos, tmp->len); if (p) { dsbCat(ret, p); xfree(p); } } } else { dsbCopy(ret, path); } dsbDestroy(tmp); return ret; }
/** * Reads a line from the smtp server using sgets(). * It will continue to read the response until the 4th character * in the line is found to be a space. Per the RFC 821 this means * that this will be the last line of response from the SMTP server * and the appropirate return value response. */ static int readResponse(dsocket *sd, dstrbuf *buf) { int retval=ERROR; dstrbuf *tmpbuf = DSB_NEW; struct timeval tv; fd_set rfds; char *timeout = getConfValue("TIMEOUT"); int readsize = 0; FD_ZERO(&rfds); FD_SET(dnetGetSock(sd), &rfds); if (timeout) { tv.tv_sec = atoi(timeout); } else { tv.tv_sec = 10; } tv.tv_usec = 0; (void) select(dnetGetSock(sd)+1, &rfds, NULL, NULL, &tv); if (FD_ISSET(dnetGetSock(sd), &rfds)) { do { dsbClear(tmpbuf); readsize = dnetReadline(sd, tmpbuf); if ((dnetErr(sd)) || (readsize <= 0)) { smtpSetErr("Lost connection with SMTP server"); retval = ERROR; break; } dsbCat(buf, tmpbuf->str); retval = SUCCESS; /* The last line of a response has a space in the 4th column */ } while (tmpbuf->str[3] != ' '); } else { smtpSetErr("Timeout(10) while trying to read from SMTP server"); retval = ERROR; } if (retval != ERROR) { retval = atoi(tmpbuf->str); } dsbDestroy(tmpbuf); return retval; }
/** * Makes a standard plain text message while taking into * account the MIME message types and boundary's needed * if and when a file is attached. **/ static int makeMessage(dstrbuf *in, dstrbuf *out, const char *border, CharSetType charset) { char *ptr=NULL; dstrbuf *enc=NULL; if (Mopts.attach) { dsbPrintf(out, "--%s\r\n", border); if (charset == IS_UTF8 || charset == IS_PARTIAL_UTF8) { if (Mopts.html) { dsbPrintf(out, "Content-Type: text/html; charset=utf-8\r\n"); } else { dsbPrintf(out, "Content-Type: text/plain; charset=utf-8\r\n"); } if (IS_PARTIAL_UTF8) { dsbPrintf(out, "Content-Transfer-Encoding: quoted-printable\r\n"); enc = mimeQpEncodeString((u_char *)in->str, true); } else { dsbPrintf(out, "Content-Transfer-Encoding: base64\r\n"); enc = mimeB64EncodeString((u_char *)in->str, in->len, true); } dsbPrintf(out, "Content-Disposition: inline\r\n\r\n"); } else if (Mopts.html) { dsbPrintf(out, "Content-Type: text/html\r\n\r\n"); enc = DSB_NEW; dsbCat(enc, in->str); } else { dsbPrintf(out, "Content-Type: text/plain\r\n\r\n"); enc = DSB_NEW; dsbCat(enc, in->str); } } else { if (charset == IS_UTF8) { enc = mimeB64EncodeString((u_char *)in->str, in->len, true); } else if (charset == IS_PARTIAL_UTF8) { enc = mimeQpEncodeString((u_char *)in->str, true); } else { enc = DSB_NEW; dsbCat(enc, in->str); } } /* Fix single dot on it's on line so we don't terminate the message prematurely. */ dstrbuf *formatted = DSB_NEW; char previous='\0'; for (ptr = enc->str; ptr && *ptr != '\0'; previous=*ptr, ptr++) { dsbCatChar(formatted, *ptr); /* If we have a dot starting on a newline. */ if ((previous == '\n' || previous == '\r') && *ptr == '.') { dsbCatChar(formatted, '.'); } } dsbDestroy(enc); dsbPrintf(out, "%s\r\n", formatted->str); if (Mopts.attach) { if (attachFiles(border, out) == ERROR) { return ERROR; } dsbPrintf(out, "\r\n\r\n--%s--\r\n", border); } dsbDestroy(formatted); return 0; }