/** * g_mime_stream_write_to_stream: * @src: source stream * @dest: destination stream * * Attempts to write the source stream to the destination stream. * * Returns: the number of bytes written or %-1 on fail. **/ ssize_t g_mime_stream_write_to_stream (GMimeStream *src, GMimeStream *dest) { ssize_t nread, nwritten, total = 0; char buf[4096]; g_return_val_if_fail (GMIME_IS_STREAM (src), -1); g_return_val_if_fail (GMIME_IS_STREAM (dest), -1); while (!g_mime_stream_eos (src)) { if ((nread = g_mime_stream_read (src, buf, sizeof (buf))) < 0) return -1; if (nread > 0) { nwritten = 0; while (nwritten < nread) { ssize_t len; if ((len = g_mime_stream_write (dest, buf + nwritten, nread - nwritten)) < 0) return -1; nwritten += len; } total += nwritten; } } return total; }
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); } } } }
/* * callback to get data from a stream */ static ssize_t g_mime_gpgme_stream_rd(GMimeStream * stream, void *buffer, size_t size) { ssize_t result; result = g_mime_stream_read(stream, buffer, size); if (result == -1 && g_mime_stream_eos(stream)) result = 0; return result; }
static void print_body (GMimeMessage *msg) { GMimeObject *body; GMimeDataWrapper *wrapper; GMimeStream *stream; body = g_mime_message_get_body (msg); if (GMIME_IS_MULTIPART(body)) body = g_mime_multipart_get_part (GMIME_MULTIPART(body), 0); if (!GMIME_IS_PART(body)) return; wrapper = g_mime_part_get_content_object (GMIME_PART(body)); if (!GMIME_IS_DATA_WRAPPER(wrapper)) return; stream = g_mime_data_wrapper_get_stream (wrapper); if (!GMIME_IS_STREAM(stream)) return; do { char buf[512]; ssize_t len; len = g_mime_stream_read (stream, buf, sizeof(buf)); if (len == -1) break; if (write (fileno(stdout), buf, len) == -1) break; if (len < (int)sizeof(buf)) break; } while (1); }
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; }
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; }
static ssize_t pkcs7_stream_read (void *stream, void *buffer, size_t size) { return g_mime_stream_read ((GMimeStream *) stream, (char *) buffer, size); }
void AnalyseMessageParse(GMimePart * mime_part) { int ichar=0,iencode =0; if( NULL==mime_part ) { printf("empty part\n"); return ; } GMimeContentEncoding ReEncoding = g_mime_part_get_content_encoding(mime_part); char* szCharset = (char*)g_mime_object_get_content_type_parameter((GMimeObject*)mime_part,"charset"); printf("charset %s\n",szCharset); { char* szCharset = (char*)g_mime_object_get_content_type_parameter((GMimeObject*)mime_part,"name"); printf("name %s\n",szCharset); GMimeContentType* pContentType = g_mime_object_get_content_type((GMimeObject*)mime_part) ; printf("The content type is: (%s/%s)\n",pContentType->type,pContentType->subtype); const char * ppp= g_mime_object_get_disposition((GMimeObject*)mime_part); if(!ppp) { goto exits; } const char * qqq=g_mime_object_get_content_disposition_parameter((GMimeObject*)mime_part,"filename"); printf("get disposition\t%s\n%s\n",ppp,qqq); if(qqq) { FILE * ps=fopen(qqq,"w+b"); printf("\n=======write to file================\n" ); GMimeStream *stream = g_mime_stream_file_new (ps); GMimeDataWrapper * content=g_mime_part_get_content_object(mime_part); g_mime_data_wrapper_write_to_stream(content,stream); fclose(ps); printf("finish writing\n"); getchar(); return ; } } exits:{} /*decode for text/plain or html*/ GMimeDataWrapper *dataWrap = g_mime_part_get_content_object(mime_part); if(!dataWrap) printf("error in dataWrap\n" ); GMimeStream * gmime_stream= g_mime_data_wrapper_get_stream(dataWrap); //encoding转码 GMimeFilter * pAttFilter = g_mime_filter_basic_new(ReEncoding,FALSE); GMimeStream* pFilterStream = g_mime_stream_filter_new(gmime_stream); iencode = g_mime_stream_filter_add (GMIME_STREAM_FILTER (pFilterStream), pAttFilter); /*create a filter convert the charset into local type*/ GMimeFilter * secondPtr = g_mime_filter_charset_new(szCharset,g_mime_charset_locale_name()); ichar = g_mime_stream_filter_add (GMIME_STREAM_FILTER (pFilterStream), secondPtr); /*convert stream into stdout*/ GMimeStream *stream = g_mime_stream_file_new (stdout); g_mime_stream_write_to_stream(pFilterStream,stream); #if 0 /*get data from stream load into char* */ char pp[10000]= {0}; int tt=g_mime_stream_read(pFilterStream,pp,10000); printf("%d\t%s\n",tt,pp); #endif g_object_unref ( pAttFilter ); g_object_unref ( secondPtr ); g_mime_stream_filter_remove((GMimeStreamFilter*)pFilterStream,ichar); g_mime_stream_filter_remove((GMimeStreamFilter*)pFilterStream,iencode); g_object_unref (pFilterStream); //g_object_unref (gmime_stream); //g_object_unref (stream); //if(NULL==szCharset) { printf("\n====>>>>====>>>>====>>>>Finish decoding this part<<<<====<<<<====<<<<====\n"); getchar(); //return ; } return ; }
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; }
static BalsaMimeWidget * balsa_mime_widget_new_unknown(BalsaMessage * bm, LibBalsaMessageBody * mime_body, const gchar * content_type) { GtkWidget *hbox; GtkWidget *button = NULL; gchar *msg; GtkWidget *msg_label; gchar *content_desc; BalsaMimeWidget *mw; gchar *use_content_type; g_return_val_if_fail(mime_body, NULL); mw = g_object_new(BALSA_TYPE_MIME_WIDGET, NULL); mw->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, BMW_VBOX_SPACE); gtk_container_set_border_width(GTK_CONTAINER(mw->widget), BMW_CONTAINER_BORDER); if (mime_body->filename) { msg = g_strdup_printf(_("File name: %s"), mime_body->filename); gtk_box_pack_start(GTK_BOX(mw->widget), gtk_label_new(msg), FALSE, FALSE, 0); g_free(msg); } /* guess content_type if not specified or if generic app/octet-stream */ /* on local mailboxes only, to avoid possibly long downloads */ if ((content_type == NULL || g_ascii_strcasecmp(content_type, "application/octet-stream") == 0) && LIBBALSA_IS_MAILBOX_LOCAL(mime_body->message->mailbox)) { GError *err = NULL; gpointer buffer; GMimeStream *stream = libbalsa_message_body_get_stream(mime_body, &err); if(!stream) { libbalsa_information(LIBBALSA_INFORMATION_ERROR, _("Error reading message part: %s"), err ? err->message : "Unknown error"); g_clear_error(&err); use_content_type = g_strdup(content_type); } else { ssize_t length = 1024 /* g_mime_stream_length(stream) */ ; ssize_t size; buffer = g_malloc(length); libbalsa_mime_stream_shared_lock(stream); size = g_mime_stream_read(stream, buffer, length); libbalsa_mime_stream_shared_unlock(stream); g_object_unref(stream); use_content_type = libbalsa_vfs_content_type_of_buffer(buffer, size); if (g_ascii_strncasecmp(use_content_type, "text", 4) == 0 && (libbalsa_text_attr_string(buffer) & LIBBALSA_TEXT_HI_BIT)) { /* Hmmm...better stick with application/octet-stream. */ g_free(use_content_type); use_content_type = g_strdup("application/octet-stream"); } g_free(buffer); } } else use_content_type = g_strdup(content_type); content_desc = libbalsa_vfs_content_description(use_content_type); if (content_desc) { msg = g_strdup_printf(_("Type: %s (%s)"), content_desc, use_content_type); g_free(content_desc); } else msg = g_strdup_printf(_("Content Type: %s"), use_content_type); msg_label = gtk_label_new(msg); g_free(msg); gtk_label_set_ellipsize(GTK_LABEL(msg_label), PANGO_ELLIPSIZE_END); gtk_box_pack_start(GTK_BOX(mw->widget), msg_label, FALSE, FALSE, 0); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, BMW_HBOX_SPACE); gtk_box_set_homogeneous(GTK_BOX(hbox), TRUE); if ((button = libbalsa_vfs_mime_button(mime_body, use_content_type, G_CALLBACK(balsa_mime_widget_ctx_menu_cb), (gpointer) mime_body))) gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); else gtk_box_pack_start(GTK_BOX(mw->widget), gtk_label_new(_("No open or view action " "defined for this content type")), FALSE, FALSE, 0); g_free(use_content_type); button = gtk_button_new_with_mnemonic(_("S_ave part")); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(balsa_mime_widget_ctx_menu_save), (gpointer) mime_body); gtk_box_pack_start(GTK_BOX(mw->widget), hbox, FALSE, FALSE, 0); return mw; }