/** * Takes a string and breaks it up based on a specific character * and returns it in a dvector */ dvector explode(const char *str, const char *delim) { bool found=false; const char *ptr=str, *dtmp=NULL; dstrbuf *buf = dsbNew(100); dvector vec = dvCreate(5, __strexplodeDestr); while (*ptr != '\0') { dtmp = delim; while (*dtmp != '\0') { if (*ptr == *dtmp) { if (buf->len > 0) { dvAddItem(&vec, xstrdup(buf->str)); dsbClear(buf); } found = true; break; } dtmp++; } if (!found) { dsbCatChar(buf, *ptr); } else { found = false; } ptr++; } /* Add the last element if there was one. */ if (buf->len > 0) { dvAddItem(&vec, xstrdup(buf->str)); } dsbDestroy(buf); return vec; }
int copyfile(const char *from, const char *to) { FILE *ffrom, *fto; dstrbuf *buf=NULL; ffrom = fopen(from, "r"); fto = fopen(to, "w"); if (!ffrom || !fto) { return -1; } buf = DSB_NEW; while (dsbFread(buf, MAXBUF, ffrom) > 0) { fwrite(buf->str, sizeof(char), buf->len, fto); dsbClear(buf); } dsbDestroy(buf); fclose(ffrom); fclose(fto); if (ferror(ffrom) || ferror(fto)) { return -1; } return 0; }
/** * Simple interface to copy over buffer into error string */ static void smtpSetErr(const char *buf) { if (!errorstr) { errorstr = DSB_NEW; } dsbClear(errorstr); dsbCopy(errorstr, buf); }
/* * Reads a line from a FILE * * Params * dsb - The dstrbuf to store the data into * file - a FILE to read the data from * * Returns * number of bytes read. */ size_t dsbReadline(dstrbuf *dsb, FILE *file) { int ch=0; size_t totalLen=0; assert(dsb != NULL); dsbClear(dsb); while ((ch = fgetc(file)) != EOF) { totalLen++; dsbCatChar(dsb, (char)ch); if (ch == '\n') { break; } } return totalLen; }
/** * 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; }
static int smtpAuthPlain(dsocket *sd, const char *user, const char *pass) { int retval = 0; dstrbuf *data=NULL; dstrbuf *up = DSB_NEW; dstrbuf *rbuf = DSB_NEW; if (writeResponse(sd, "AUTH PLAIN\r\n") < 0) { smtpSetErr("Socket write error: smtp_auth_plain"); retval = ERROR; goto end; } #ifdef DEBUG_SMTP printf("--> AUTH PLAIN\n"); fflush(stdout); #endif retval = readResponse(sd, rbuf); if (retval != 334) { if (retval != ERROR) { smtpSetErr(rbuf->str); } retval = ERROR; goto end; } #ifdef DEBUG_SMTP printf("<-- %s\n", rbuf->str); fflush(stdout); #endif dsbPrintf(up, "%c%s%c%s", '\0', user, '\0', pass); data = mimeB64EncodeString((u_char *)up->str, up->len, false); if (writeResponse(sd, "%s\r\n", data->str) < 0) { smtpSetErr("Socket write error: smtp_auth_plain"); retval = ERROR; goto end; } #ifdef DEBUG_SMTP printf("--> %s\n", data->str); fflush(stdout); #endif dsbClear(rbuf); retval = readResponse(sd, rbuf); if (retval != 235) { if (retval != ERROR) { smtpSetErr(rbuf->str); } retval = ERROR; goto end; } #ifdef DEBUG_SMTP printf("<-- %s\n", rbuf->str); fflush(stdout); #endif end: dsbDestroy(up); dsbDestroy(data); dsbDestroy(rbuf); return retval; }