summaryrefslogtreecommitdiffstats
path: root/libmail/attachments.H
blob: 33f11f1a1ccc9738c13ab5373305fccba7110de2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
** Copyright 2004, Double Precision Inc.
**
** See COPYING for distribution information.
*/
#ifndef libmail_attachments_H
#define libmail_attachments_H

///////////////////////////////////////////////////////////////////////////
//
// mail::Attachment is a versatile object that's used to build arbitrary
// MIME objects.
//
// A mail::Attachment object can represent a:
//
// 1) A content-containing MIME entity.  The mail::Attachment object
//    can optionally select the most appropriate encoding method.
//
// 2) A multipart MIME entity.
//
// 3) A message/rfc822 entity.


#include <string>
#include <vector>
#include <stdio.h>
#include "namespace.H"
#include "structure.H"
#include "rfc822/encode.h"

LIBMAIL_START

class Attachment {

	std::string headers; // All entities: the headers

	std::string transfer_encoding;
	// If not empty - this is a content entity

	FILE *content_fp; // File descriptor with the content, or
	std::string content_string; // The content in memory

	mail::Attachment *message_rfc822; // This is a message/rfc822 object

	std::vector<mail::Attachment *> parts; // This is a multipart object

	std::string multipart_type;
	mail::mimestruct::parameterList multipart_parameters;

	bool try_boundary(std::string, int level);

	void common_init();
	void common_fd_init(int content_fd);
public:

	//
	// The headers parameter in the following constructions should ideally
	// be created using mail::Header::list.  In all cases the string MUST
	// have a trailing newline.
	//

	Attachment(std::string headers, int content_fd);
	// Content attachment, autodetect encoding

	Attachment(std::string headers, int content_fd,
		   std::string charset,
		   std::string transfer_encoding="");
	// Content attachment uses the given encoding.  transfer_encoding may
	// be an empty string, in which case the encoding is picked based on
	// charset.

	// The following two constructors receive the literal content,
	// instead of a file descriptor.
	Attachment(std::string headers, std::string content_string);
	Attachment(std::string headers, std::string content_string,
		   std::string charset,
		   std::string transfer_encoding="");

	//
	// Create a multipart attachment.  The Content-Type: header is
	// extracted from 'headers' and parsed.
	//
	// If Content-Type: is message/rfc822, the parts vector's length must
	// be exactly 1.

	Attachment(std::string headers,
		   const std::vector<Attachment *> &parts);
	Attachment(std::string headers,
		   const std::vector<Attachment *> &parts,
		   std::string multipart_type,
		   const mail::mimestruct::parameterList
		   &multipart_parameters);
private:
	void check_multipart_encoding();

	void common_multipart_init();
public:

	~Attachment();


	// Generating the MIME object.

	void begin();
	std::string generate(bool &error);

	// Return the next chunk of the generated object.
	// Returns an empty string when done, or if an error occured.
	// (If error=false, we're done)

private:
	void begin_recursive();

	bool generating;
	std::vector<mail::Attachment *>::iterator multipart_iterator;

	struct libmail_encode_info encode_info;

	static int callback_func(const char *, size_t, void *);

	std::string encoded;

public:

	// NOTE: the copy constructor and assignment operator does NOT
	// duplicate the subtree.

	Attachment(const Attachment &);
	Attachment &operator=(const Attachment &);


private:
	std::string find_header(const char *,
				std::string::iterator &,
				std::string::iterator &);
	void add_content_encoding();
public:
	static std::string find_header(const char *,
				       std::string &,
				       std::string::iterator &,
				       std::string::iterator &);
};


LIBMAIL_END

#endif