+
+ subject = tny_header_get_subject (header);
+ sender = tny_header_get_from (header);
+
+ flags = tny_header_get_flags (header);
+
+ hit->msgid = msg_url;
+ hit->subject = g_strdup_or_null (subject);
+ hit->sender = g_strdup_or_null (sender);
+ hit->folder = g_strdup_or_null (tny_folder_get_name (folder));
+ hit->msize = tny_header_get_message_size (header);
+ hit->has_attachment = flags & TNY_HEADER_FLAG_ATTACHMENTS;
+ hit->is_unread = ! (flags & TNY_HEADER_FLAG_SEEN);
+ hit->timestamp = tny_header_get_date_received (header);
+
+ return g_list_prepend (list, hit);
+}
+
+/** Call this until it returns FALSE or nread is set to 0.
+ *
+ * @result: FALSE is something failed. */
+static gboolean
+read_chunk (TnyStream *stream, char *buffer, gsize count, gsize *nread)
+{
+ gsize _nread = 0;
+ gssize res = 0;
+
+ while (_nread < count) {
+ res = tny_stream_read (stream,
+ buffer + _nread,
+ count - _nread);
+ if (res == -1) { /* error */
+ *nread = _nread;
+ return FALSE;
+ }
+
+ _nread += res;
+
+ if (res == 0) { /* no more bytes read. */
+ *nread = _nread;
+ return TRUE;
+ }
+ }
+
+ *nread = _nread;
+ return TRUE;
+}
+
+#ifdef MODEST_HAVE_OGS
+static gboolean
+search_mime_part_ogs (TnyMimePart *part, ModestSearch *search)
+{
+ TnyStream *stream = NULL;
+ char buffer[4096];
+ const gsize len = sizeof (buffer);
+ gsize nread = 0;
+ gboolean is_text_html = FALSE;
+ gboolean found = FALSE;
+ gboolean res = FALSE;
+
+ gboolean is_text = tny_mime_part_content_type_is (part, "text/*");
+ if (!is_text) {
+ g_debug ("%s: tny_mime_part_content_type_is() failed to find a "
+ "text/* MIME part. Content type is %s",
+ __FUNCTION__, "Unknown (calling tny_mime_part_get_content_type(part) causes a deadlock)");
+
+ /* Retry with specific MIME types, because the wildcard seems to fail
+ * in tinymail.
+ * Actually I'm not sure anymore that it fails, so we could probalby
+ * remove this later: murrayc */
+ is_text = (
+ tny_mime_part_content_type_is (part, "text/plain") ||
+ tny_mime_part_content_type_is (part, "text/html") );
+
+ if (is_text) {
+ g_debug ("%s: Retryting with text/plain or text/html succeeded",
+ __FUNCTION__);
+ }
+ }
+
+ if (!is_text) {
+ return FALSE;
+ }
+
+ is_text_html = tny_mime_part_content_type_is (part, "text/html");
+
+ stream = tny_mime_part_get_stream (part);
+
+ res = read_chunk (stream, buffer, len, &nread);
+ while (res && (nread > 0)) {
+ /* search->text_searcher was instantiated in modest_search_folder(). */
+
+ if (is_text_html) {
+
+ found = ogs_text_searcher_search_html (search->text_searcher,
+ buffer,
+ nread,
+ nread < len);
+ } else {
+ found = ogs_text_searcher_search_text (search->text_searcher,
+ buffer,
+ nread);
+ }
+
+ if (found) {
+ break;
+ }
+
+ nread = 0;
+ res = read_chunk (stream, buffer, len, &nread);
+ }
+
+ if (!found) {
+ found = ogs_text_searcher_search_done (search->text_searcher);
+ }
+
+ ogs_text_searcher_reset (search->text_searcher);
+
+ /* debug stuff:
+ if (!found) {
+ buffer[len -1] = 0;
+ printf ("DEBUG: %s: query %s was not found in message text: %s\n",
+ __FUNCTION__, search->query, buffer);
+
+ } else {
+ printf ("DEBUG: %s: found.\n", __FUNCTION__);
+ }
+ */
+
+ return found;
+}
+
+#else
+
+static gboolean
+search_mime_part_strcmp (TnyMimePart *part, ModestSearch *search)
+{
+ TnyStream *stream;
+ char buffer[8193];
+ char *chunk[2];
+ gssize len;
+ gsize nread;
+ gboolean found;
+ gboolean res;
+
+ if (! tny_mime_part_content_type_is (part, "text/*")) {
+ g_debug ("%s: No text MIME part found.\n", __FUNCTION__);
+ return FALSE;
+ }
+
+ found = FALSE;
+ len = (sizeof (buffer) - 1) / 2;
+
+ if (strlen (search->body) > len) {
+ g_warning ("Search term bigger then chunk."
+ "We might not find everything");
+ }
+
+ stream = tny_mime_part_get_stream (part);
+
+ memset (buffer, 0, sizeof (buffer));
+ chunk[0] = buffer;
+ chunk[1] = buffer + len;
+
+ res = read_chunk (stream, chunk[0], len, &nread);
+
+ if (res == FALSE) {
+ goto done;
+ }
+
+ found = !modest_text_utils_utf8_strcmp (search->body,
+ buffer,
+ TRUE);
+ if (found) {
+ goto done;
+ }
+
+ /* This works like this:
+ * buffer: [ooooooooooo|xxxxxxxxxxxx|\0]
+ * ^chunk[0] ^chunk[1]
+ * we have prefilled chunk[0] now we always read into chunk[1]
+ * and then move the content of chunk[1] to chunk[0].
+ * The idea is to prevent not finding search terms that are
+ * spread across 2 reads:
+ * buffer: [ooooooooTES|Txxxxxxxxxxx|\0]
+ * We should catch that because we always search the whole
+ * buffer not only the chunks.
+ *
+ * Of course that breaks for search terms > sizeof (chunk)
+ * but sizeof (chunk) should be big enough I guess (see
+ * the g_warning in this function)
+ * */
+ while ((res = read_chunk (stream, chunk[1], len, &nread))) {
+ buffer[len + nread] = '\0';
+
+ found = !modest_text_utils_utf8_strcmp (search->body,
+ buffer,
+ TRUE);
+
+ if (found) {
+ break;
+ }
+
+ /* also move the \0 */
+ g_memmove (chunk[0], chunk[1], len + 1);
+ }
+
+done:
+ g_object_unref (stream);
+ return found;