+ /*
+ * If we have snoop turned on, output the data.
+ *
+ * Note here; if we don't have a CR or LF at the end, save the data
+ * in ns_snoop_savebuf for later and print it next time.
+ */
+
+ if (nsc->ns_snoop) {
+ unsigned int snoopoutlen = netoutlen;
+ const char *snoopoutbuf = (const char *) nsc->ns_outbuffer;
+
+ while (snoopoutlen > 0) {
+ const char *end = strpbrk(snoopoutbuf, "\r\n");
+ unsigned int outlen;
+
+ if (! end) {
+ if (nsc->ns_snoop_savebuf) {
+ nsc->ns_snoop_savebuf = mh_xrealloc(nsc->ns_snoop_savebuf,
+ strlen(nsc->ns_snoop_savebuf) +
+ snoopoutlen + 1);
+ strncat(nsc->ns_snoop_savebuf, snoopoutbuf, snoopoutlen);
+ } else {
+ nsc->ns_snoop_savebuf = mh_xmalloc(snoopoutlen + 1);
+ strncpy(nsc->ns_snoop_savebuf, snoopoutbuf, snoopoutlen);
+ nsc->ns_snoop_savebuf[snoopoutlen] = '\0';
+ }
+ break;
+ }
+
+ outlen = end - snoopoutbuf;
+
+#ifdef CYRUS_SASL
+ if (nsc->sasl_seclayer)
+ fprintf(stderr, "(sasl-encrypted) ");
+#endif /* CYRUS_SASL */
+#ifdef TLS_SUPPORT
+ if (nsc->tls_active)
+ fprintf(stderr, "(tls-encrypted) ");
+#endif /* TLS_SUPPORT */
+ fprintf(stderr, "=> ");
+ if (nsc->ns_snoop_cb) {
+ const char *ptr;
+ unsigned int cb_len = outlen;
+
+ if (nsc->ns_snoop_savebuf) {
+ cb_len += strlen(nsc->ns_snoop_savebuf);
+ nsc->ns_snoop_savebuf = mh_xrealloc(nsc->ns_snoop_savebuf,
+ outlen);
+ ptr = nsc->ns_snoop_savebuf;
+ } else {
+ ptr = snoopoutbuf;
+ }
+
+ nsc->ns_snoop_cb(nsc, ptr, cb_len, nsc->ns_snoop_context);
+
+ if (nsc->ns_snoop_savebuf) {
+ free(nsc->ns_snoop_savebuf);
+ nsc->ns_snoop_savebuf = NULL;
+ }
+ } else {
+ if (nsc->ns_snoop_savebuf) {
+ fprintf(stderr, "%s", nsc->ns_snoop_savebuf);
+ free(nsc->ns_snoop_savebuf);
+ nsc->ns_snoop_savebuf = NULL;
+ }
+ fprintf(stderr, "%.*s\n", outlen, snoopoutbuf);
+ }
+
+ /*
+ * Alright, hopefully any previous leftover data is done,
+ * and we have the current line output. Move things past the
+ * next CR/LF.
+ */
+
+ snoopoutlen -= outlen;
+ snoopoutbuf += outlen;
+
+ if (snoopoutlen > 0 && *snoopoutbuf == '\r') {
+ snoopoutlen--;
+ snoopoutbuf++;
+ }
+
+ if (snoopoutlen > 0 && *snoopoutbuf == '\n') {
+ snoopoutlen--;
+ snoopoutbuf++;
+ }
+ }
+ }
+