struct imclient, outbuf
Patrick Welche
prlw1 at newn.cam.ac.uk
Fri Apr 4 14:42:25 EST 2003
In trying to figure out what is going on in imclient_write, I simplified
struct imclient, and moved from pointers to indices - a matter of taste,
I know, but it seems the reply buffer is handled that way..
(One could also s/writelen/imclient->outlen/g)
Cheers,
Patrick
Index: imclient.c
===================================================================
RCS file: /cvs/src/cyrus/lib/imclient.c,v
retrieving revision 1.77
diff -u -r1.77 imclient.c
--- imclient.c 13 Feb 2003 20:15:40 -0000 1.77
+++ imclient.c 4 Apr 2003 19:37:33 -0000
@@ -120,9 +120,7 @@
/* Data to be output to server */
char outbuf[IMCLIENT_BUFSIZE];
- char *outptr;
- size_t outleft;
- char *outstart;
+ size_t outlen;
/* Replies being received from server */
char *replybuf;
@@ -263,8 +261,10 @@
(*imclient)->saslconn = NULL;
(*imclient)->saslcompleted = 0;
(*imclient)->servername = xstrdup(hp->h_name);
- (*imclient)->outptr = (*imclient)->outstart = (*imclient)->outbuf;
- (*imclient)->outleft = (*imclient)->maxplain = sizeof((*imclient)->outbuf);
+ (*imclient)->outlen = 0;
+ (*imclient)->replylen = 0;
+ (*imclient)->alloc_replybuf = 0;
+ (*imclient)->maxplain = sizeof((*imclient)->outbuf);
(*imclient)->interact_results = NULL;
imclient_addcallback(*imclient,
"", 0, (imclient_proc_t *) 0, (void *)0,
@@ -626,41 +625,50 @@
*/
void imclient_write(struct imclient *imclient, const char *s, size_t len)
{
+ size_t outleft;
+
assert(imclient);
assert(s);
- /* If no data pending for output, reset the buffer */
- if (imclient->outptr == imclient->outstart) {
- imclient->outstart = imclient->outptr = imclient->outbuf;
- imclient->outleft = imclient->maxplain;
- }
-
+ outleft = imclient->maxplain - imclient->outlen;
/* While we don't have room to buffer all the output */
- while (len > imclient->outleft) {
- /* Copy as much data as will fit in output buffer */
- memcpy(imclient->outptr, s, imclient->outleft);
- imclient->outptr += imclient->outleft;
- s += imclient->outleft;
- len -= imclient->outleft;
- imclient->outleft = 0;
-
- /* Process events until output buffer is flushed */
- while (imclient->outptr != imclient->outstart) {
- imclient_processoneevent(imclient);
- }
-
- /* Reset the buffer */
- imclient->outstart = imclient->outptr = imclient->outbuf;
- imclient->outleft = imclient->maxplain;
+ while (len > outleft) {
+ /* Copy as much data as will fit in output buffer */
+ memcpy(imclient->outbuf+imclient->outlen, s, outleft);
+ imclient->outlen += outleft;
+ s += outleft;
+ len -= outleft;
+
+ /* Process events until output buffer is flushed */
+ while (imclient->outlen) {
+ imclient_processoneevent(imclient);
+ } /* Should only be called once. If not, then not all plain text
+ * was successfully writen in non sasl case
+ */
+ outleft = imclient->maxplain; /* - imclient->outlen; == 0 */
}
/* Copy remaining data to output buffer */
- memcpy(imclient->outptr, s, len);
- imclient->outptr += len;
- imclient->outleft -= len;
+ memcpy(imclient->outbuf+imclient->outlen, s, len);
+ imclient->outlen += len;
}
/*
+ * http://bugzilla.andrew.cmu.edu/show_bug.cgi?id=333
+ *
+ * Opened: 2000-10-13 00:02
+ *
+ * imclient doesn't correctly parse literals. this will bite any
+ * serious imclient application that consistently fetches things with
+ * literals.
+ *
+ * imclient.c, around line 730, uses the variable 'len' in a place
+ * where it clearly isn't applicable. this is the heart of the bug,
+ * but we need to fix it so that literals that don't end lines are
+ * still handled correctly.
+ */
+
+/*
* On the connection 'imclient', handle the input 'buf' of size 'len'
* from the server. Invoke callbacks as appropriate.
*/
@@ -1006,13 +1014,13 @@
assert(imclient);
for (;;) {
- writelen = imclient->outptr - imclient->outstart;
+ writelen = imclient->outlen;
if ((imclient->saslcompleted==1) && (writelen>0)) {
unsigned int cryptlen=0;
const char *cryptptr=NULL;
- if (sasl_encode(imclient->saslconn, imclient->outstart, writelen,
+ if (sasl_encode(imclient->saslconn, imclient->outbuf, writelen,
&cryptptr,&cryptlen)!=SASL_OK)
{
/* XXX encoding error */
@@ -1032,7 +1040,7 @@
#endif /* HAVE_SSL */
if (n > 0) {
- imclient->outstart += writelen;
+ imclient->outlen = 0; /* what if cryptlen != n ? */
return;
}
@@ -1047,17 +1055,17 @@
#ifdef HAVE_SSL
if (imclient->tls_on==1)
{
- n = SSL_write(imclient->tls_conn, imclient->outstart, writelen);
+ n = SSL_write(imclient->tls_conn, imclient->outbuf, writelen);
} else {
- n = write(imclient->fd, imclient->outstart, writelen);
+ n = write(imclient->fd, imclient->outbuf, writelen);
}
#else /* HAVE_SSL */
- n = write(imclient->fd, imclient->outstart, writelen);
+ n = write(imclient->fd, imclient->outbuf, writelen);
#endif /* HAVE_SSL */
if (n > 0) {
- imclient->outstart += n;
+ imclient->outlen -= n;
return;
}
/* XXX Also EPIPE & the like? */
More information about the Info-cyrus
mailing list