static void filter_client_data(char* data, ssize_t size) { char* lf; while ((lf = memchr(data, LF, size)) != 0) { str_catb(&linebuf, data, lf - data + 1); filter_client_line(); write_server(linebuf.s, linebuf.len); linebuf.len = 0; size -= lf - data + 1; data = lf + 1; } str_catb(&linebuf, data, size); }
int session_putenv(const char* s) { if (session.env.len > 0) if (!str_catc(&session.env, 0)) return 0; return str_catb(&session.env, s, strlen(s) + 1); }
/** Sort a string. \param s The string to sort. \param sep The character which delimits the substrings. \param count The number of substrings within \c s (set to \c -1 if not known). \param fn The comparison function. Defaults to a function that works like \c memcmp. \note This function allocates a temporary array of substring pointers, and so may return \c 0 if memory allocation fails. The string itself is not reallocated. */ int str_sort(str* s, char sep, long count, int (*fn)(const str_sortentry* a, const str_sortentry* b)) { str_sortentry* ptrs; const char* ptr; const char* end; long i; str tmp = {0,0,0}; if (count == -1) { for (count = 0, ptr = s->s, end = s->s+s->len; ptr != 0 && ptr < end; ++count) { ptr = memchr(ptr, sep, end-ptr); if (ptr) ++ptr; } } if ((ptrs = alloca(count * sizeof *ptrs)) == 0) return 0; if (!str_copy(&tmp, s)) { str_free(&tmp); return 0; } if (fn == 0) fn = default_cmp; for (i = 0, ptr = tmp.s, end = tmp.s+tmp.len; i < count; ++i) { const char* ptrend = memchr(ptr, sep, end-ptr); if (ptrend == 0) ptrend = end; ptrs[i].str = ptr; ptrs[i].len = ptrend - ptr; ptr = ptrend + 1; } qsort(ptrs, count, sizeof(*ptrs), (int (*)(const void*,const void*))fn); str_truncate(s, 0); for (i = 0; i < count; i++) { str_catb(s, ptrs[i].str, ptrs[i].len); str_catc(s, sep); } str_free(&tmp); return 1; }
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; }
static void handle_auth_login_response(str* line, ssize_t offset) { saw_auth_login = 0; if (!base64decode(line->s + offset, line->len + offset, &tmpstr)) username.len = 0; else { make_username(tmpstr.s, tmpstr.len, "AUTH LOGIN "); line->len = offset; base64encode(username.s, username.len, line); str_catb(line, CRLF, 2); } }
static int setup_env(void) { const char* s; const char* colon; struct stat st; if (cvm_fact_mailbox != 0 && (s = getenv("SETUP_ENV")) != 0 && strcmp(s, "dovecot") == 0) { /* This tells Dovecot that its environment has already been set up. */ if (putenv("DOVECONF_ENV=1") != 0) return 0; /* Use the file type to set the prefix to mbox: or maildir: * Assume missing files are mboxes. */ s = (stat(cvm_fact_mailbox, &st) == 0 && S_ISDIR(st.st_mode)) ? "maildir:" : "mbox:"; /* Use cmd for temporary storage of the substituted mailbox name */ if (!str_copys(&cmd, s)) return 0; s = cvm_fact_mailbox; while ((colon = strchr(s, ':')) != 0) { if (!str_catb(&cmd, s, colon-s) || !str_catb(&cmd, "::", 2)) return 0; s = colon + 1; } if (!str_cats(&cmd, s)) return 0; cvm_fact_mailbox = cmd.s; } return cvm_setenv() && setenv("IMAPLOGINTAG", tag.s, 1) == 0 && setenv("AUTHENTICATED", cvm_fact_username, 1) == 0; }
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); } }
static const response* data_block(const char* bytes, unsigned long len) { if (databytes == 0) { /* First line is always Received, log the first two lines. */ const char* ch; ch = strchr(bytes, '\n'); str_copyb(&tmp, bytes, ch-bytes); bytes = ch + 1; if ((ch = strchr(bytes, '\n')) != 0) str_catb(&tmp, bytes, ch-bytes); msg1(tmp.s); } databytes += len; return 0; }
int base64decode(const char* data, unsigned long size, str* dest) { unsigned char bin[3]; int decoded; dest->len = 0; while (size) { if (data[0] == CR || data[0] == LF) size = 0; if (size < 4) break; if ((decoded = base64_decode_part(data, bin)) <= 0) break; data += 4; size -= 4; if (!str_catb(dest, (char*)bin, decoded)) die_oom(111); } return size ? 0 : 1; }
static void handle_auth_plain_response(str* line, ssize_t offset) { int start; int end; saw_auth_plain = 0; if (base64decode(line->s + offset, line->len - offset, &tmpstr)) { /* tmpstr should now contain "AUTHORIZATION\0AUTHENTICATION\0PASSWORD" */ if ((start = str_findfirst(&tmpstr, NUL)) >= 0 && (end = str_findnext(&tmpstr, NUL, ++start)) > start) { make_username(tmpstr.s + start, end - start, "AUTH PLAIN "); str_splice(&tmpstr, start, end - start, &username); line->len = offset; base64encode(tmpstr.s, tmpstr.len, line); str_catb(line, CRLF, 2); } } }