Zig Requires Chilkat v11.0.0+
Zig
Load .eml and Examine the Structure, Attachments, and Related Items
See more Email Object Examples
Demonstrates how to load examine the MIME structure of a .eml, and also examine the attachment and related item filenames, attached messages, and multipart/report and DSN information.Chilkat Zig Downloads
const std = @import("std");
const chilkat = @import("chilkat");
pub fn main(init: std.process.Init) !void {
const alloc = init.arena.allocator();
// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
const eml_path = "C:/AAWorkarea/beatrix/roesner.eml";
const mime = try chilkat.Mime.init();
defer mime.deinit();
mime.loadMimeFile(eml_path) catch {
std.debug.print("{s}\n", .{try mime.getLastErrorText(alloc)});
return;
};
std.debug.print("---- MIME structure ----\n", .{});
std.debug.print("{s}\n", .{try mime.getStructure(alloc, "text")});
std.debug.print("------------------------\n", .{});
const email = try chilkat.Email.init();
defer email.deinit();
try email.loadEml(eml_path);
// Was this a signed and/or encrypted email?
// If so, then loading the .eml automatically unwraps
// (i.e. verifies signatures and decrypts) and the resultant
// email is what existed prior to signing/encrypting.
std.debug.print("Email was Signed: {}\n", .{email.getReceivedSigned()});
std.debug.print("Email was Encrypted: {}\n", .{email.getReceivedEncrypted()});
if (email.getReceivedSigned()) {
std.debug.print("Signature(s) valid = {}\n", .{email.getSignaturesValid()});
}
if (email.getReceivedEncrypted()) {
std.debug.print("Decrypted successfully = {}\n", .{email.getDecrypted()});
}
var i: i32 = 0;
const num_attach = email.getNumAttachments();
std.debug.print("Number of attachments = {d}\n", .{num_attach});
while (i < num_attach) {
std.debug.print("---- Attachment {d}\n", .{i});
// Examine the filename (if any)
std.debug.print("filename: {s}\n", .{try email.getAttachmentFilename(alloc, i)});
// Examine the content-ID (if any)
std.debug.print("Content-ID: {s}\n", .{try email.getAttachmentContentID(alloc, i)});
// Examine the content-type
std.debug.print("Content-Type: {s}\n", .{try email.getAttachmentContentType(alloc, i)});
// Examine the content-disposition
std.debug.print("Content-Disposition{s}\n", .{try email.getAttachmentHeader(alloc, i, "content-disposition")});
// Examine the attachment size:
std.debug.print("Size (in bytes) of the attachment: {d}\n", .{email.getAttachmentSize(i)});
i = i + 1;
}
std.debug.print("--\n", .{});
// Now for the related items.
// Note: A MIME sub-part can potentially be both a related item AND an attachment.
// The typical case is when the item is contained under the multipart/related enclosure and
// the item also has a "Content-Disposition" header indicating "attachment".
// The location within multipart/related makes it a "related item", yet the Content-Disposition can also make it semantically an attachment.
// Related items and attachments are not necessarily mutually exclusive.
const num_related = email.getNumRelatedItems();
std.debug.print("Number of related items = {d}\n", .{num_related});
i = 0;
while (i < num_related) {
std.debug.print("---- Related Item {d}\n", .{i});
// Examine the filename (if any)
std.debug.print("filename: {s}\n", .{try email.getRelatedFilename(alloc, i)});
// Examine the content-ID (if any)
std.debug.print("Content-ID: {s}\n", .{try email.getRelatedContentID(alloc, i)});
// Examine the content-type
std.debug.print("Content-Type: {s}\n", .{try email.getRelatedContentType(alloc, i)});
// Examine the content-location (if any)
std.debug.print("Content-Location{s}\n", .{try email.getRelatedContentLocation(alloc, i)});
i = i + 1;
}
// The email could also have attached messages.
// An attached message is another email that was attached to this email.
const em = try chilkat.Email.init();
defer em.deinit();
const num_attached_messages = email.getNumAttachedMessages();
std.debug.print("Number of attached messages = {d}\n", .{num_attached_messages});
i = 0;
while (i < num_attached_messages) {
std.debug.print("---- Attached message {d}\n", .{i});
// Examine the attached email
email.getAttachedEmail(i, em) catch {};
std.debug.print("from: {s}\n", .{try em.getFrom(alloc)});
std.debug.print("subject: {s}\n", .{try em.getSubject(alloc)});
i = i + 1;
}
// An email could also be a multipart/report email.
// This is a DSN (Delivery Status Notification)
// The NumReports property indicates how many "reports" exist.
const num_reports = email.getNumReports();
std.debug.print("Number of reports = {d}\n", .{num_reports});
i = 0;
while (i < num_reports) {
std.debug.print("---- Report {d}\n", .{i});
// Get the raw report data...
std.debug.print("{s}\n", .{try email.getReport(alloc, i)});
i = i + 1;
}
// If the email is a multipart/report, then the information
// from the message/delivery-status part of the email can be retrieved:
if (email.isMultipartReport()) {
std.debug.print("--- Delivery Status Information:\n", .{});
std.debug.print("Status: {s}\n", .{try email.getDeliveryStatusInfo(alloc, "Status")});
std.debug.print("Action: {s}\n", .{try email.getDeliveryStatusInfo(alloc, "Action")});
std.debug.print("Reporting-MTA: {s}\n", .{try email.getDeliveryStatusInfo(alloc, "Reporting-MTA")});
const json_dsn_info = try chilkat.JsonObject.init();
defer json_dsn_info.deinit();
email.getDsnInfo(json_dsn_info) catch {};
json_dsn_info.setEmitCompact(false);
std.debug.print("{s}\n", .{try json_dsn_info.emit(alloc)});
}
}