Ejemplo n.º 1
0
static void gmime_callback(SIPE_UNUSED_PARAMETER GMimeObject *parent,
			   GMimeObject *part,
			   gpointer user_data)
{
	GMimeDataWrapper *data = g_mime_part_get_content_object((GMimePart *)part);

	if (data) {
		GMimeStream *stream = g_mime_data_wrapper_get_stream(data);

		if (stream) {
			ssize_t length = g_mime_stream_length(stream);

			if (length != -1) {
				gchar *content = g_malloc(length + 1);

				if (g_mime_stream_read(stream, content, length) == length) {
					struct gmime_callback_data *cd = user_data;
					GSList *fields = gmime_fields_to_nameval(part);

					(*(cd->callback))(cd->user_data, fields, content, length);

					sipe_utils_nameval_free(fields);
				}
				g_free(content);
			}
		}
	}
}
Ejemplo n.º 2
0
static void
test_cat_seek (GMimeStream *whole, struct _StreamPart *parts, int bounded)
{
	struct _StreamPart *part = parts;
	GMimeStream *stream, *cat;
	gint64 offset, len;
	Exception *ex;
	int fd;
	
	if (whole->bound_end != -1) {
		len = whole->bound_end - whole->bound_start;
	} else if ((len = g_mime_stream_length (whole)) == -1) {
		ex = exception_new ("unable to get original stream length");
		throw (ex);
	}
	
	cat = g_mime_stream_cat_new ();
	
	while (part != NULL) {
		d(fprintf (stderr, "adding %s start=%lld, end=%lld...\n",
			   part->filename, part->pstart, part->pend));
		
		if ((fd = open (part->filename, O_RDONLY, 0)) == -1) {
			ex = exception_new ("could not open `%s': %s", part->filename, g_strerror (errno));
			g_object_unref (cat);
			throw (ex);
		}
		
		stream = g_mime_stream_fs_new_with_bounds (fd, part->pstart, bounded ? part->pend : -1);
		g_mime_stream_cat_add_source ((GMimeStreamCat *) cat, stream);
		g_object_unref (stream);
		
		part = part->next;
	}
	
	/* calculate a random seek offset to compare at */
	offset = (gint64) (len * (rand () / (RAND_MAX + 1.0)));
	
	if (g_mime_stream_seek (whole, offset, GMIME_STREAM_SEEK_SET) == -1) {
		ex = exception_new ("could not seek to %lld in original stream: %s",
				    offset, g_strerror (errno));
		throw (ex);
	}
	
	if (g_mime_stream_seek (cat, offset, GMIME_STREAM_SEEK_SET) == -1) {
		ex = exception_new ("could not seek to %lld: %s",
				    offset, g_strerror (errno));
		throw (ex);
	}
	
	if (check_streams_match (whole, cat, "stream.part*", TRUE) == -1) {
		ex = exception_new ("streams did not match");
		g_object_unref (cat);
		throw (ex);
	}
}
Ejemplo n.º 3
0
static void
test_stream_mem (const char *filename)
{
	/* Note: this also tests g_mime_stream_write_to_stream */
	GMimeStream *stream, *fstream;
	int fd;
	
	if ((fd = open (filename, O_RDONLY, 0)) == -1) {
		v(fprintf (stderr, "failed to open %s: %s\n", filename, g_strerror (errno)));
		return;
	}
	
	testsuite_start ("GMimeStreamMem");
	
	fstream = g_mime_stream_fs_new (fd);
	stream = g_mime_stream_mem_new ();
	
	testsuite_check ("GMimeStreamMem::read()");
	try {
		if (g_mime_stream_write_to_stream (fstream, stream) == -1)
			throw (exception_new ("g_mime_stream_write_to_stream() failed"));
		
		if (g_mime_stream_length (stream) != g_mime_stream_length (fstream))
			throw (exception_new ("stream lengths didn't match"));
		
		test_stream_read (stream, filename);
		
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("GMimeStreamMem::read() failed: %s",
					ex->message);
	} finally;
	
	g_object_unref (fstream);
	g_object_unref (stream);
	
	testsuite_end ();
}
Ejemplo n.º 4
0
gint64
mux_message_part_get_size (MuxMessagePart *self)
{
	GMimeStream *mstream;
	
	g_return_val_if_fail (MUX_IS_MESSAGE_PART(self), FALSE);
	
	if (!GMIME_IS_PART(self->mime_object))
		return 0;

	mstream = get_mime_stream (self->mime_object, NULL);
	if (!mstream)
		return -1;

	return g_mime_stream_length (mstream);
}
Ejemplo n.º 5
0
/* note: this will return -1 in case of error or if the size is
 * unknown */
static ssize_t
get_part_size (GMimePart *part)
{
	GMimeDataWrapper *wrapper;
	GMimeStream *stream;

	wrapper = g_mime_part_get_content_object (part);
	if (!GMIME_IS_DATA_WRAPPER(wrapper))
		return -1;

	stream = g_mime_data_wrapper_get_stream (wrapper);
	if (!stream)
		return -1; /* no stream -> size is 0 */
	else
		return g_mime_stream_length (stream);

	/* NOTE: stream/wrapper are owned by gmime, no unreffing */
}
Ejemplo n.º 6
0
static void
format_omitted_part_meta_sprinter (sprinter_t *sp, GMimeObject *meta, GMimePart *part)
{
    const char *content_charset = g_mime_object_get_content_type_parameter (meta, "charset");
    const char *cte = g_mime_object_get_header (meta, "content-transfer-encoding");
    GMimeDataWrapper *wrapper = g_mime_part_get_content_object (part);
    GMimeStream *stream = g_mime_data_wrapper_get_stream (wrapper);
    ssize_t content_length = g_mime_stream_length (stream);

    if (content_charset != NULL) {
	sp->map_key (sp, "content-charset");
	sp->string (sp, content_charset);
    }
    if (cte != NULL) {
	sp->map_key (sp, "content-transfer-encoding");
	sp->string (sp, cte);
    }
    if (content_length >= 0) {
	sp->map_key (sp, "content-length");
	sp->integer (sp, content_length);
    }
}
Ejemplo n.º 7
0
static gboolean
streams_match (GMimeStream **streams, const char *filename)
{
	char buf[4096], dbuf[4096], errstr[1024];
	gint64 len, totalsize, totalread = 0;
	size_t nread, size;
	ssize_t n;
	
	v(fprintf (stdout, "Matching original stream (%" G_GINT64_FORMAT " -> %" G_GINT64_FORMAT ") with %s (%" G_GINT64_FORMAT ", %" G_GINT64_FORMAT ")... ",
		   streams[0]->position, streams[0]->bound_end, filename,
		   streams[1]->position, streams[1]->bound_end));
	
	if (streams[0]->bound_end != -1) {
		totalsize = streams[0]->bound_end - streams[0]->position;
	} else if ((len = g_mime_stream_length (streams[0])) == -1) {
		sprintf (errstr, "Error: Unable to get length of original stream: %s\n", g_strerror (errno));
		goto fail;
	} else if (len < (streams[0]->position - streams[0]->bound_start)) {
		sprintf (errstr, "Error: Overflow on original stream?\n");
		goto fail;
	} else {
		totalsize = len - (streams[0]->position - streams[0]->bound_start);
	}
	
	while (totalread < totalsize) {
		if ((n = g_mime_stream_read (streams[0], buf, sizeof (buf))) <= 0)
			break;
		
		size = n;
		nread = 0;
		totalread += n;
		
		d(fprintf (stderr, "read %" G_GSIZE_FORMAT " bytes from stream[0]\n", size));
		
		do {
			if ((n = g_mime_stream_read (streams[1], dbuf + nread, size - nread)) <= 0) {
				d(fprintf (stderr, "stream[1] read() returned %" G_GSSIZE_FORMAT ", EOF\n", n));
				break;
			}
			d(fprintf (stderr, "read %" G_GSSIZE_FORMAT " bytes from stream[1]\n", n));
			nread += n;
		} while (nread < size);
		
		if (nread < size) {
			sprintf (errstr, "Error: `%s' appears to be truncated, short %" G_GSIZE_FORMAT "+ bytes\n",
				 filename, size - nread);
			goto fail;
		}
		
		if (memcmp (buf, dbuf, size) != 0) {
			sprintf (errstr, "Error: `%s': content does not match\n", filename);
			goto fail;
		} else {
			d(fprintf (stderr, "%" G_GSIZE_FORMAT " bytes identical\n", size));
		}
	}
	
	if (totalread < totalsize) {
		sprintf (errstr, "Error: expected more data from stream[0]\n");
		goto fail;
	}
	
	if ((n = g_mime_stream_read (streams[1], buf, sizeof (buf))) > 0) {
		sprintf (errstr, "Error: `%s' appears to contain extra content\n", filename);
		goto fail;
	}
	
	v(fputs ("passed\n", stdout));
	
	return TRUE;
	
 fail:
	
	v(fputs ("failed\n", stdout));
	v(fputs (errstr, stderr));
	
	return FALSE;
}
Ejemplo n.º 8
0
int main (int argc, char **argv)
{
	const char *datadir = "data/cat";
	struct _StreamPart *list, *tail, *n;
	gboolean failed = FALSE;
	gint64 wholelen, left;
	GMimeStream *whole;
	guint32 part = 0;
	gint64 start = 0;
	char *filename;
	struct stat st;
	gint64 len;
	int fd, i;
	
	srand (time (NULL));
	
	g_mime_init (0);
	
	testsuite_init (argc, argv);
	
	for (i = 1; i < argc; i++) {
		if (argv[i][0] != '-') {
			datadir = argv[i];
			break;
		}
	}
	
	if (i < argc) {
		if (stat (datadir, &st) == -1) {
			if (errno == ENOENT) {
				g_mkdir_with_parents (datadir, 0755);
				if (stat (datadir, &st) == -1)
					return EXIT_FAILURE;
			} else
				return EXIT_FAILURE;
		}
		
		if (S_ISREG (st.st_mode)) {
			/* test a particular input file */
			if ((fd = open (argv[i], O_RDONLY, 0)) == -1)
				return EXIT_FAILURE;
			
			filename = g_strdup (argv[i]);
			whole = g_mime_stream_fs_new (fd);
		} else if (S_ISDIR (st.st_mode)) {
			/* use path as test suite data dir */
			whole = random_whole_stream (argv[i], &filename);
		} else {
			return EXIT_FAILURE;
		}
	} else {
		whole = random_whole_stream (datadir, &filename);
	}
	
	if ((wholelen = g_mime_stream_length (whole)) == -1) {
		fprintf (stderr, "Error: length of test stream unknown\n");
		g_object_unref (whole);
		return EXIT_FAILURE;
	} else if (wholelen == 64) {
		fprintf (stderr, "Error: length of test stream is unsuitable for testing\n");
		g_object_unref (whole);
		return EXIT_FAILURE;
	}
	
	list = NULL;
	tail = (struct _StreamPart *) &list;
	
	left = wholelen;
	while (left > 0) {
		len = 1 + (gint64) (left * (rand () / (RAND_MAX + 1.0)));
		n = g_new (struct _StreamPart, 1);
		sprintf (n->filename, "%s.%u", filename, part++);
		n->pstart = (gint64) 0; /* FIXME: we could make this a random offset */
		n->pend = n->pstart + len;
		n->wend = start + len;
		n->wstart = start;
		tail->next = n;
		tail = n;
		
		start += len;
		left -= len;
	}
	
	tail->next = NULL;
	
	testsuite_start ("GMimeStreamCat");
	
	for (i = 0; i < G_N_ELEMENTS (checks) && !failed; i++) {
		testsuite_check (checks[i].what);
		try {
			checks[i].check (whole, list, checks[i].bounded);
			testsuite_check_passed ();
		} catch (ex) {
			testsuite_check_failed ("%s failed: %s", checks[i].what,
						ex->message);
			failed = TRUE;
		} finally;
	}
	
	testsuite_end ();
	
	while (list != NULL) {
		n = list->next;
		if (!failed)
			unlink (list->filename);
		g_free (list);
		list = n;
	}
	
	g_object_unref (whole);
	
	if (!failed)
		unlink (filename);
	
	g_free (filename);
	
	g_mime_shutdown ();
	
	return testsuite_exit ();
}
Ejemplo n.º 9
0
static void
test_cat_substream (GMimeStream *whole, struct _StreamPart *parts, int bounded)
{
	GMimeStream *stream, *cat, *sub1, *sub2;
	struct _StreamPart *part = parts;
	gint64 start, end, len;
	Exception *ex;
	int fd;
	
	if (whole->bound_end != -1) {
		len = whole->bound_end - whole->bound_start;
	} else if ((len = g_mime_stream_length (whole)) == -1) {
		ex = exception_new ("unable to get original stream length");
		throw (ex);
	}
	
	cat = g_mime_stream_cat_new ();
	
	while (part != NULL) {
		d(fprintf (stderr, "adding %s start=%lld, end=%lld...\n",
			   part->filename, part->pstart, part->pend));
		
		if ((fd = open (part->filename, O_RDONLY, 0)) == -1) {
			ex = exception_new ("could not open `%s': %s", part->filename, g_strerror (errno));
			g_object_unref (cat);
			throw (ex);
		}
		
		stream = g_mime_stream_fs_new_with_bounds (fd, part->pstart, bounded ? part->pend : -1);
		g_mime_stream_cat_add_source ((GMimeStreamCat *) cat, stream);
		g_object_unref (stream);
		
		part = part->next;
	}
	
	/* calculate a random start/end offsets */
	start = (gint64) (len * (rand () / (RAND_MAX + 1.0)));
	if (rand () % 2)
		end = start + (gint64) ((len - start) * (rand () / (RAND_MAX + 1.0)));
	else
		end = -1;
	
	if (!(sub1 = g_mime_stream_substream (whole, start, end))) {
		ex = exception_new ("could not substream the original stream: %s",
				    g_strerror (errno));
		g_object_unref (cat);
		throw (ex);
	}
	
	if (!(sub2 = g_mime_stream_substream (cat, start, end))) {
		ex = exception_new ("%s", g_strerror (errno));
		g_object_unref (sub1);
		g_object_unref (cat);
		throw (ex);
	}
	
	g_object_unref (cat);
	
	if (check_streams_match (sub1, sub2, "stream.part*", TRUE) == -1) {
		ex = exception_new ("streams did not match");
		g_object_unref (sub1);
		g_object_unref (sub2);
		throw (ex);
	}
	
	g_object_unref (sub1);
	g_object_unref (sub2);
}
Ejemplo n.º 10
0
static int
check_streams_match (GMimeStream *orig, GMimeStream *dup, const char *filename, int check_overflow)
{
	char buf[4096], dbuf[4096], errstr[1024];
	gint64 len, totalsize, totalread = 0;
	size_t nread, size;
	ssize_t n;
	
	v(fprintf (stdout, "Matching original stream (%" G_GINT64_FORMAT " -> %" G_GINT64_FORMAT ") with %s (%" G_GINT64_FORMAT ", %" G_GINT64_FORMAT ")... ",
		   orig->position, orig->bound_end, filename, dup->position, dup->bound_end));
	
	if (orig->bound_end != -1) {
		totalsize = orig->bound_end - orig->position;
	} else if ((len = g_mime_stream_length (orig)) == -1) {
		sprintf (errstr, "Error: Unable to get length of original stream\n");
		goto fail;
	} else if (len < (orig->position - orig->bound_start)) {
		sprintf (errstr, "Error: Overflow on original stream?\n");
		goto fail;
	} else {
		totalsize = len - (orig->position - orig->bound_start);
	}
	
	while (totalread < totalsize) {
		if ((n = g_mime_stream_read (orig, buf, sizeof (buf))) <= 0)
			break;
		
		size = n;
		nread = 0;
		totalread += n;
		
		d(fprintf (stderr, "read %zu bytes from original stream\n", size));
		
		do {
			if ((n = g_mime_stream_read (dup, dbuf + nread, size - nread)) <= 0) {
				d(fprintf (stderr, "dup read() returned %zd, EOF\n", n));
				break;
			}
			d(fprintf (stderr, "read %zd bytes from dup stream\n", n));
			nread += n;
		} while (nread < size);
		
		if (nread < size) {
			sprintf (errstr, "Error: `%s' appears to be truncated, short %zu+ bytes\n",
				 filename, size - nread);
			goto fail;
		}
		
		if (memcmp (buf, dbuf, size) != 0) {
			sprintf (errstr, "Error: `%s': content does not match\n", filename);
			goto fail;
		} else {
			d(fprintf (stderr, "%zu bytes identical\n", size));
		}
	}
	
	if (totalread < totalsize) {
		sprintf (errstr, "Error: expected more data from original stream\n");
		goto fail;
	}
	
	if (check_overflow && (n = g_mime_stream_read (dup, buf, sizeof (buf))) > 0) {
		sprintf (errstr, "Error: `%s' appears to contain extra content\n", filename);
		goto fail;
	}
	
	v(fputs ("passed\n", stdout));
	
	return 0;
	
 fail:
	
	v(fputs ("failed\n", stdout));
	v(fputs (errstr, stderr));
	
	return -1;
}
Ejemplo n.º 11
0
static gboolean
streams_match (GMimeStream *istream, GMimeStream *ostream)
{
	char buf[4096], dbuf[4096], errstr[1024], *bufptr, *bufend, *dbufptr;
	gint64 len, totalsize, totalread = 0;
	size_t nread, size;
	gint64 offset = 0;
	ssize_t n;
	
	v(fprintf (stdout, "Checking if streams match... "));
	
	if (istream->bound_end != -1) {
		totalsize = istream->bound_end - istream->position;
	} else if ((len = g_mime_stream_length (istream)) == -1) {
		sprintf (errstr, "Error: Unable to get length of original stream\n");
		goto fail;
	} else if (len < (istream->position - istream->bound_start)) {
		sprintf (errstr, "Error: Overflow on original stream?\n");
		goto fail;
	} else {
		totalsize = len - (istream->position - istream->bound_start);
	}
	
	while (totalread < totalsize) {
		if ((n = g_mime_stream_read (istream, buf, sizeof (buf))) <= 0)
			break;
		
		size = n;
		nread = 0;
		totalread += n;
		
		d(fprintf (stderr, "read %zu bytes from istream\n", size));
		
		do {
			if ((n = g_mime_stream_read (ostream, dbuf + nread, size - nread)) <= 0) {
				fprintf (stderr, "ostream's read(%p, dbuf + %zu, %zu) returned %zd, EOF\n", ostream, nread, size - nread, n);
				break;
			}
			d(fprintf (stderr, "read %zd bytes from ostream\n", n));
			nread += n;
		} while (nread < size);
		
		if (nread < size) {
			sprintf (errstr, "Error: ostream appears to be truncated, short %zu+ bytes\n",
				 size - nread);
			goto fail;
		}
		
		bufend = buf + size;
		dbufptr = dbuf;
		bufptr = buf;
		
		while (bufptr < bufend) {
			if (*bufptr != *dbufptr)
				break;
			
			dbufptr++;
			bufptr++;
		}
		
		if (bufptr < bufend) {
			sprintf (errstr, "Error: content does not match at offset %" G_GINT64_FORMAT "\n",
				 offset + (bufptr - buf));
			/*fprintf (stderr, "-->'%.*s'<--\nvs\n-->'%.*s'<--\n",
			  bufend - bufptr, bufptr, bufend - bufptr, dbufptr);*/
			goto fail;
		} else {
			d(fprintf (stderr, "%zu bytes identical\n", size));
		}
		
		offset += size;
	}
	
	if (totalread < totalsize) {
		strcpy (errstr, "Error: expected more data from istream\n");
		goto fail;
	}
	
	if ((n = g_mime_stream_read (ostream, buf, sizeof (buf))) > 0) {
		strcpy (errstr, "Error: ostream appears to contain extra content\n");
		goto fail;
	}
	
	v(fputs ("passed\n", stdout));
	
	return TRUE;
	
 fail:
	
	v(fputs ("failed\n", stdout));
	v(fputs (errstr, stderr));
	
	return FALSE;
}