summary refs log tree commit diff stats
path: root/libotr/libotr-4.1.1/toolkit/readotr.c
diff options
context:
space:
mode:
Diffstat (limited to 'libotr/libotr-4.1.1/toolkit/readotr.c')
-rw-r--r--libotr/libotr-4.1.1/toolkit/readotr.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/libotr/libotr-4.1.1/toolkit/readotr.c b/libotr/libotr-4.1.1/toolkit/readotr.c
new file mode 100644
index 0000000..77ffcbb
--- /dev/null
+++ b/libotr/libotr-4.1.1/toolkit/readotr.c
@@ -0,0 +1,91 @@
+/*
+ *  Off-the-Record Messaging Toolkit
+ *  Copyright (C) 2004-2012  Ian Goldberg, Chris Alexander, Nikita Borisov
+ *                           <otr@cypherpunks.ca>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* system headers */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct {
+    char *data;
+    size_t len;
+    size_t alloclen;
+} Buffer;
+
+static void buf_new(Buffer *bufp)
+{
+    bufp->data = NULL;
+    bufp->len = 0;
+    bufp->alloclen = 0;
+}
+
+static void buf_put(Buffer *bufp, const char *str, size_t len)
+{
+    while (bufp->len + len + 1 > bufp->alloclen) {
+	char *newdata = realloc(bufp->data, bufp->alloclen + 1024);
+	if (!newdata) {
+	    fprintf(stderr, "Out of memory!\n");
+	    exit(1);
+	}
+	bufp->data = newdata;
+	bufp->alloclen += 1024;
+    }
+    memmove(bufp->data + bufp->len, str, len);
+    bufp->len += len;
+    bufp->data[bufp->len] = '\0';
+}
+
+static void buf_putc(Buffer *bufp, char c)
+{
+    buf_put(bufp, &c, 1);
+}
+
+/* Read from the given stream until we see a complete OTR Key Exchange
+ * or OTR Data message.  Return a newly-allocated pointer to a copy of
+ * this message, which the caller should free().  Returns NULL if no
+ * such message could be found. */
+char *readotr(FILE *stream)
+{
+    int seen = 0;
+    const char header[] = "?OTR:";  /* There are no '?' chars other than
+				       the leading one */
+    int headerlen = strlen(header);
+    Buffer buf;
+
+    while(seen < headerlen) {
+	int c = fgetc(stream);
+	if (c == EOF) return NULL;
+	else if (c == header[seen]) seen++;
+	else if (c == header[0]) seen = 1;
+	else seen = 0;
+    }
+
+    buf_new(&buf);
+    buf_put(&buf, header, headerlen);
+
+    /* Look for the trailing '.' */
+    while(1) {
+	int c = fgetc(stream);
+	if (c == EOF) break;
+	buf_putc(&buf, c);
+	if (c == '.') break;
+    }
+
+    return buf.data;
+}