Viewing file:
imapwrite.c (3.44 KB) -rw-rw-rw-Select action/file-type:

(
+) |

(
+) |

(
+) |
Code (
+) |
Session (
+) |

(
+) |
SDB (
+) |

(
+) |

(
+) |

(
+) |

(
+) |

(
+) |
/*
** Copyright 1998 - 2006 Double Precision, Inc.
** See COPYING for distribution information.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#if TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#else
#if HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <time.h>
#endif
#endif
#include "imapwrite.h"
static char outbuf[BUFSIZ]; /* Ye olde output buffer */
static size_t outbuf_cnt=0; /* How much stuff's in ye olde output buffer */
extern FILE *debugfile;
extern unsigned long bytes_sent_count; /* counter for sent bytes (imapwrite.c) */
extern void disconnected();
void writeflush()
{
const char *p=outbuf;
unsigned s=outbuf_cnt;
time_t t, tend;
fd_set fds;
struct timeval tv;
int n;
if (s == 0) return;
time(&t);
tend=t+SOCKET_TIMEOUT;
if (debugfile)
{
fprintf(debugfile, "WRITE: ");
if (fwrite(p, 1, s, debugfile) == 1)
fprintf(debugfile, "\n");
fflush(debugfile);
}
while (t < tend)
{
FD_ZERO(&fds);
FD_SET(1, &fds);
tv.tv_sec=tend-t;
tv.tv_usec=0;
/* BUG: if client closes connection BEFORE we flush it, select "stucks"
* until timeout. To workaround this, we should "write" first, and then
* if we get EPIPE connection is already closed. Othervise, try select
*/
if ((n=write(1, p, s)) <= 0)
{
if (errno == EPIPE ||
select(2, 0, &fds, 0, &tv) <= 0 ||
!FD_ISSET(1, &fds) ||
(n=write(1, p, s)) <= 0)
{
disconnected();
return;
}
}
bytes_sent_count += n;
p += n;
s -= n;
if (s == 0) break;
time(&t);
}
if (s) disconnected();
outbuf_cnt=0;
}
void writemem(const char *s, size_t l)
{
size_t n;
while (l)
{
n=sizeof(outbuf) - outbuf_cnt;
if (n >= l)
{
memcpy(outbuf+outbuf_cnt, s, l);
outbuf_cnt += l;
break;
}
if (n == 0)
{
writeflush();
continue;
}
if (n > l) n=l;
memcpy(outbuf+outbuf_cnt, s, n);
outbuf_cnt += n;
l -= n;
s += n;
}
}
void writes(const char *s)
{
writemem(s, strlen(s));
}
void writen(unsigned long n)
{
char buf[40];
sprintf(buf, "%lu", n);
writemem(buf, strlen(buf));
}
void writeqs(const char *s)
{
size_t i=strlen(s), j;
while (i)
{
for (j=0; j<i; j++)
{
if ( s[j] == '"' || s[j] == '\\')
{
writemem(s, j);
writemem("\\", 1);
writemem(s+j, 1);
++j;
s += j;
i -= j;
j=0;
break;
}
#if 0
if (s[j] == '&')
{
writemem(s, j);
writemem("&-", 2);
++j;
s += j;
i -= j;
j=0;
break;
}
if (s[j] < ' ' || s[j] >= 0x7F)
{
char *q;
writemem(s, j);
++j;
s += j;
i -= j;
for (j=0; j<i; j++)
if (s[j] >= ' ' && s[j] < 0x7F)
break;
q=imap_utf7_encode(s, j);
if (!q) write_error_exit(0);
writemem("&", 1);
writes(q);
writemem("-", 1);
s += j;
i -= j;
j=0;
break;
}
#endif
}
writemem(s, j);
s += j;
i -= j;
}
}
void write_error_exit(const char *funcname)
{
outbuf_cnt=0;
writes("* BYE [ALERT] Fatal error: ");
if (funcname && *funcname)
{
writes(funcname);
writes(": ");
}
if (errno)
{
#if HAVE_STRERROR
const char *p;
p=strerror(errno);
#else
char p[40];
sprintf(p, "Error %d", (int)errno);
#endif
writes(p);
}
writes("\r\n");
writeflush();
if (funcname && *funcname)
{
fprintf(stderr, "ERR: %s: %s\n", getenv("AUTHENTICATED"),
funcname);
fflush(stderr);
}
_exit(1);
}