#ifdef HAVE_OPENSSL
static void serv_read_ssl(CtdlIPC *ipc, char *buf, unsigned int bytes);
static void serv_write_ssl(CtdlIPC *ipc, const char *buf, unsigned int nbytes);
-static void ssl_lock(int mode, int n, const char *file, int line);
static void endtls(SSL *ssl);
#ifdef THREADED_CLIENT
static unsigned long id_callback(void);
int CtdlIPCQuit(CtdlIPC *ipc)
{
register int ret = 221; /* Default to successful quit */
- char aaa[128];
+ char aaa[SIZ];
CtdlIPC_lock(ipc);
if (ipc->sock > -1) {
int CtdlIPCLogout(CtdlIPC *ipc)
{
register int ret;
- char aaa[128];
+ char aaa[SIZ];
CtdlIPC_lock(ipc);
CtdlIPC_putline(ipc, "LOUT");
rret[0]->RRaide = extract_int(cret, 8);
rret[0]->RRnewmail = extract_long(cret, 9);
rret[0]->RRfloor = extract_int(cret, 10);
+ rret[0]->RRflags2 = extract_int(cret, 14);
} else {
free(*rret);
*rret = NULL;
/* If doing a MIME thing, pull out the extra headers */
if (as_mime == 4) {
do {
- if (!strncasecmp(bbb, "Content-type: ", 14)) {
+ if (!strncasecmp(bbb, "Content-type:", 13)) {
extract_token(mret[0]->content_type, bbb, 0, '\n', sizeof mret[0]->content_type);
- strcpy(mret[0]->content_type,
- &mret[0]->content_type[14]);
+ strcpy(mret[0]->content_type, &mret[0]->content_type[13]);
striplt(mret[0]->content_type);
/* strip out ";charset=" portion. FIXME do something with
}
}
+ if (!strncasecmp(bbb, "X-Citadel-MSG4-Partnum:", 23)) {
+ extract_token(mret[0]->mime_chosen, bbb, 0, '\n', sizeof mret[0]->mime_chosen);
+ strcpy(mret[0]->mime_chosen, &mret[0]->mime_chosen[23]);
+ striplt(mret[0]->mime_chosen);
+ }
remove_token(bbb, 0, '\n');
} while ((bbb[0] != 0) && (bbb[0] != '\n'));
remove_token(bbb, 0, '\n');
/* ENT0 */
-int CtdlIPCPostMessage(CtdlIPC *ipc, int flag, const struct ctdlipcmessage *mr, char *cret)
+int CtdlIPCPostMessage(CtdlIPC *ipc, int flag, int *subject_required, const struct ctdlipcmessage *mr, char *cret)
{
register int ret;
char cmd[SIZ];
mr->anonymous, mr->type, mr->subject, mr->author);
ret = CtdlIPCGenericCommand(ipc, cmd, mr->text, strlen(mr->text), NULL,
NULL, cret);
+ if ((flag == 0) && (subject_required != NULL)) {
+ /* Is the server strongly recommending that the user enter a message subject? */
+ if ((cret[3] != '\0') && (cret[4] != '\0')) {
+ *subject_required = extract_int(&cret[4], 1);
+ }
+
+
+ }
return ret;
}
int CtdlIPCGetSystemConfigByType(CtdlIPC *ipc, const char *mimetype,
char **listing, char *cret)
{
+ register int ret;
char *aaa;
size_t bytes;
aaa = malloc(strlen(mimetype) + 13);
if (!aaa) return -1;
sprintf(aaa, "CONF GETSYS|%s", mimetype);
- return CtdlIPCGenericCommand(ipc, aaa, NULL, 0,
+ ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0,
listing, &bytes, cret);
+ free(aaa);
+ return ret;
}
int CtdlIPCSetSystemConfigByType(CtdlIPC *ipc, const char *mimetype,
const char *listing, char *cret)
{
+ register int ret;
char *aaa;
if (!cret) return -2;
aaa = malloc(strlen(mimetype) + 13);
if (!aaa) return -1;
sprintf(aaa, "CONF PUTSYS|%s", mimetype);
- return CtdlIPCGenericCommand(ipc, aaa, listing, strlen(listing),
+ ret = CtdlIPCGenericCommand(ipc, aaa, listing, strlen(listing),
NULL, NULL, cret);
+ free(aaa);
+ return ret;
}
/* QDIR */
int CtdlIPCDirectoryLookup(CtdlIPC *ipc, const char *address, char *cret)
{
+ register int ret;
char *aaa;
if (!address) return -2;
if (!aaa) return -1;
sprintf(aaa, "QDIR %s", address);
- return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
+ ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
+ free(aaa);
+ return ret;
}
char aaa[SIZ];
char buf[4096];
FILE *fd;
+ int ferr;
if (!cret) return -1;
if (!path) return -1;
}
if (progress_gauge_callback)
progress_gauge_callback(ipc, 1, 1);
- return (!ferror(fd) ? ret : -2);
+ ferr = ferror(fd);
+ fclose(fd);
+ return (!ferr ? ret : -2);
}
/*
* send binary to server
*/
-static void serv_write(CtdlIPC *ipc, const char *buf, unsigned int nbytes)
+void serv_write(CtdlIPC *ipc, const char *buf, unsigned int nbytes)
{
unsigned int bytes_written = 0;
int retval;
}
+#ifdef THREADED_CLIENT
+static void ssl_lock(int mode, int n, const char *file, int line)
+{
+ if (mode & CRYPTO_LOCK)
+ pthread_mutex_lock(Critters[n]);
+ else
+ pthread_mutex_unlock(Critters[n]);
+}
+#endif /* THREADED_CLIENT */
+
+
static void CtdlIPC_init_OpenSSL(void)
{
int a;
}
-static void ssl_lock(int mode, int n, const char *file, int line)
-{
-#ifdef THREADED_CLIENT
- if (mode & CRYPTO_LOCK)
- pthread_mutex_lock(Critters[n]);
- else
- pthread_mutex_unlock(Critters[n]);
-#endif /* THREADED_CLIENT */
-}
#ifdef THREADED_CLIENT
static unsigned long id_callback(void) {
#endif /* HAVE_OPENSSL */
+int
+ReadNetworkChunk(CtdlIPC* ipc)
+{
+ fd_set read_fd;
+ int tries;
+ int ret = 0;
+ int err = 0;
+ struct timeval tv;
+ size_t n;
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 1000;
+ tries = 0;
+ n = 0;
+ while (1)
+ {
+ errno=0;
+ FD_ZERO(&read_fd);
+ FD_SET(ipc->sock, &read_fd);
+ ret = select(ipc->sock+1, &read_fd, NULL, NULL, &tv);
+
+// fprintf(stderr, "\nselect failed: %d %d %s\n", ret, err, strerror(err));
+
+ if (ret > 0) {
+
+ *(ipc->BufPtr) = '\0';
+ n = read(ipc->sock, ipc->BufPtr, ipc->BufSize - (ipc->BufPtr - ipc->Buf) - 1);
+ if (n > 0) {
+ ipc->BufPtr[n]='\0';
+ ipc->BufUsed += n;
+ return n;
+ }
+ else
+ return n;
+ }
+ else if (ret < 0) {
+ if (!(errno == EINTR || errno == EAGAIN))
+ error_printf( "\nselect failed: %d %s\n", err, strerror(err));
+ return -1;
+ }/*
+ else {
+ tries ++;
+ if (tries >= 10)
+ n = read(ipc->sock, ipc->BufPtr, ipc->BufSize - (ipc->BufPtr - ipc->Buf) - 1);
+ if (n > 0) {
+ ipc->BufPtr[n]='\0';
+ ipc->BufUsed += n;
+ return n;
+ }
+ else {
+ connection_died(ipc, 0);
+ return -1;
+ }
+ }*/
+ }
+}
+
/*
* input string from socket - implemented in terms of serv_read()
*/
static void CtdlIPC_getline(CtdlIPC* ipc, char *buf)
{
- int i;
+ int i, ntries;
+ char *aptr, *bptr, *aeptr, *beptr;
- /* Read one character at a time. */
- for (i = 0;; i++) {
- serv_read(ipc, &buf[i], 1);
- if (buf[i] == '\n' || i == (SIZ-1))
- break;
- }
+// error_printf("---\n");
- /* If we got a long line, discard characters until the newline. */
- if (i == (SIZ-1))
- while (buf[i] != '\n')
- serv_read(ipc, &buf[i], 1);
+ beptr = buf + SIZ;
+#if defined(HAVE_OPENSSL)
+ if (ipc->ssl) {
+
+ /* Read one character at a time. */
+ for (i = 0;; i++) {
+ serv_read(ipc, &buf[i], 1);
+ if (buf[i] == '\n' || i == (SIZ-1))
+ break;
+ }
+
+ /* If we got a long line, discard characters until the newline. */
+ if (i == (SIZ-1))
+ while (buf[i] != '\n')
+ serv_read(ipc, &buf[i], 1);
+
+ /* Strip the trailing newline (and carriage return, if present) */
+ if (i>=0 && buf[i] == 10) buf[i--] = 0;
+ if (i>=0 && buf[i] == 13) buf[i--] = 0;
+ }
+ else
+#endif
+ {
+ if (ipc->Buf == NULL)
+ {
+ ipc->BufSize = SIZ;
+ ipc->Buf = (char*) malloc(ipc->BufSize + 10);
+ *(ipc->Buf) = '\0';
+ ipc->BufPtr = ipc->Buf;
+ }
- /* Strip the trailing newline (and carriage return, if present) */
- if (buf[i] == 10) buf[i--] = 0;
- if (buf[i] == 13) buf[i--] = 0;
+ ntries = 0;
+// while ((ipc->BufUsed == 0)||(ntries++ > 10))
+ if (ipc->BufUsed == 0)
+ ReadNetworkChunk(ipc);
+
+//// if (ipc->BufUsed != 0) while (1)
+ bptr = buf;
+
+ while (1)
+ {
+ aptr = ipc->BufPtr;
+ aeptr = ipc->Buf + ipc->BufSize;
+ while ((aptr < aeptr) &&
+ (bptr < beptr) &&
+ (*aptr != '\0') &&
+ (*aptr != '\n'))
+ *(bptr++) = *(aptr++);
+ if ((*aptr == '\n') && (aptr < aeptr))
+ {
+ /* Terminate it right, remove the line breaks */
+ while ((aptr < aeptr) && ((*aptr == '\n') || (*aptr == '\r')))
+ aptr ++;
+ while ((aptr < aeptr ) && (*(aptr + 1) == '\0') )
+ aptr ++;
+ *(bptr++) = '\0';
+// fprintf(stderr, "parsing %d %d %d - %d %d %d %s\n", ipc->BufPtr - ipc->Buf, aptr - ipc->BufPtr, ipc->BufUsed , *aptr, *(aptr-1), *(aptr+1), buf);
+ if ((bptr > buf + 1) && (*(bptr-1) == '\r'))
+ *(--bptr) = '\0';
+
+ /* is there more in the buffer we need to read later? */
+ if (ipc->Buf + ipc->BufUsed > aptr)
+ {
+ ipc->BufPtr = aptr;
+ }
+ else
+ {
+ ipc->BufUsed = 0;
+ ipc->BufPtr = ipc->Buf;
+ }
+// error_printf("----bla6\n");
+ return;
+
+ }/* should we move our read stuf to the bufferstart so we have more space at the end? */
+ else if ((ipc->BufPtr != ipc->Buf) &&
+ (ipc->BufUsed > (ipc->BufSize - (ipc->BufSize / 4))))
+ {
+ size_t NewBufSize = ipc->BufSize * 2;
+ int delta = (ipc->BufPtr - ipc->Buf);
+ char *NewBuf;
+
+ /* if the line would end after our buffer, we should use a bigger buffer. */
+ NewBuf = (char *)malloc (NewBufSize + 10);
+ memcpy (NewBuf, ipc->BufPtr, ipc->BufUsed - delta);
+ free(ipc->Buf);
+ ipc->Buf = ipc->BufPtr = NewBuf;
+ ipc->BufUsed -= delta;
+ ipc->BufSize = NewBufSize;
+ }
+ if (ReadNetworkChunk(ipc) <0)
+ {
+// error_printf("----bla\n");
+ return;
+ }
+ }
+/// error_printf("----bl45761%s\nipc->BufUsed");
+ }
+// error_printf("----bla1\n");
}
void CtdlIPC_chat_recv(CtdlIPC* ipc, char* buf)
ipc->uploading = 0;
ipc->last_command_sent = 0L;
ipc->network_status_cb = NULL;
+ ipc->Buf = NULL;
+ ipc->BufUsed = 0;
+ ipc->BufPtr = NULL;
strcpy(cithost, DEFAULT_HOST); /* default host */
strcpy(citport, DEFAULT_PORT); /* default port */
shutdown(ipc->sock, 2); /* Close it up */
ipc->sock = -1;
}
+ if (ipc->Buf != NULL)
+ free (ipc->Buf);
+ ipc->Buf = NULL;
+ ipc->BufPtr = NULL;
ifree(ipc);
}