Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commit f7aa784c authored by rswindell's avatar rswindell

Added smb_getcontenttype(): returns the MIME content-type of the message

or NULL if not relevant (not a MIME-encoded message).
Added smb_countattachments(): returns the number of file attachments in a
MIME-encoded message.
Added SMBMSGTXT_NO_TAILS definition to be used in place of '0' for
common smb_getmsgtxt() mode argument value.
The amount of white-space after "Content-Type:" and the content-type value
is now more flexible (0 or +1 spaces/tabs are fine).
parent d51367d8
......@@ -99,13 +99,16 @@
#define SMB_ALL_REFS 0 /* Free all references to data */
#define GETMSGTXT_TAILS (1<<0) /* Get message tail(s) */
#define GETMSGTXT_NO_BODY (1<<1) /* Don't retrieve message body */
#define GETMSGTXT_NO_HFIELDS (1<<2) /* Don't include text header fields */
/* smb_getmsgtxt() mode flags */
#define GETMSGTXT_TAILS (1<<0) /* Incude message tail(s) */
#define GETMSGTXT_NO_BODY (1<<1) /* Exclude message body */
#define GETMSGTXT_NO_HFIELDS (1<<2) /* Exclude text header fields */
#define GETMSGTXT_PLAIN (1<<3) /* Get plaintext portion only of MIME-encoded body (all, otherwise) */
/* common smb_getmsgtxt() mode values */
#define GETMSGTXT_BODY_ONLY GETMSGTXT_NO_HFIELDS
#define GETMSGTXT_TAIL_ONLY (GETMSGTXT_TAILS|GETMSGTXT_NO_BODY|GETMSGTXT_NO_HFIELDS)
#define GETMSGTXT_ALL GETMSGTXT_TAILS
#define GETMSGTXT_NO_TAILS 0 /* Exclude message tails(s) */
#define SMB_IS_OPEN(smb) ((smb)->shd_fp!=NULL)
......@@ -266,9 +269,11 @@ SMBEXPORT enum smb_net_type SMBCALL smb_get_net_type_by_addr(const char* addr);
SMBEXPORT void SMBCALL smb_dump_msghdr(FILE* fp, smbmsg_t* msg);
/* smbtxt.c */
SMBEXPORT char* SMBCALL smb_getmsgtxt(smb_t* smb, smbmsg_t* msg, ulong mode);
SMBEXPORT char* SMBCALL smb_getplaintext(smbmsg_t* msg, char* buf);
SMBEXPORT uint8_t* SMBCALL smb_getattachment(smbmsg_t* msg, char* buf, char* filename, size_t filename_len, uint32_t* filelen, int index);
SMBEXPORT char* SMBCALL smb_getmsgtxt(smb_t*, smbmsg_t*, ulong mode);
SMBEXPORT char* SMBCALL smb_getplaintext(smbmsg_t*, char* body);
SMBEXPORT char* SMBCALL smb_getcontenttype(smbmsg_t*);
SMBEXPORT uint8_t* SMBCALL smb_getattachment(smbmsg_t*, char* body, char* filename, size_t filename_len, uint32_t* filelen, int index);
SMBEXPORT ulong SMBCALL smb_countattachments(smb_t*, smbmsg_t*, const char* body);
/* smbfile.c */
SMBEXPORT int SMBCALL smb_feof(FILE* fp);
......
......@@ -338,8 +338,8 @@ static char* mime_getcontent(char* buf, const char* content_type, const char* co
int found = 0;
if(content_match != NULL) {
match_len = sprintf(match1, "Content-Type: %s;", content_match);
sprintf(match2, "Content-Type: %s\r", content_match);
match_len = sprintf(match1, "%s;", content_match);
sprintf(match2, "%s\r", content_match);
}
if(depth > 2)
......@@ -372,8 +372,11 @@ static char* mime_getcontent(char* buf, const char* content_type, const char* co
continue;
for(content_type = txt; content_type < p; content_type++) {
SKIP_WHITESPACE(content_type);
if(strnicmp(content_type, "Content-Type:", 13) == 0)
if(strnicmp(content_type, "Content-Type:", 13) == 0) {
content_type += 13;
SKIP_WHITESPACE(content_type);
break;
}
FIND_CHAR(content_type, '\r');
}
if(content_type >= p)
......@@ -400,23 +403,31 @@ static char* mime_getcontent(char* buf, const char* content_type, const char* co
return NULL;
}
/* Returns the MIME content-type or NULL if not a MIME-encoded message */
char* SMBCALL smb_getcontenttype(smbmsg_t* msg)
{
int i;
for(i = 0; i < msg->total_hfields; i++) {
if(msg->hfield[i].type == RFC822HEADER) {
if(strnicmp((char*)msg->hfield_dat[i], "Content-Type:", 13) == 0) {
char* result = msg->hfield_dat[i] + 13;
SKIP_WHITESPACE(result);
return result;
}
}
}
return NULL; /* not MIME */
}
/* Get just the plain-text portion of a MIME-encoded message body */
/* Returns NULL if there is no MIME-encoded plain-text portion of the message */
char* SMBCALL smb_getplaintext(smbmsg_t* msg, char* buf)
{
int i;
char* txt;
char* content_type = NULL;
char* content_type = smb_getcontenttype(msg);
enum content_transfer_encoding xfer_encoding = CONTENT_TRANFER_ENCODING_NONE;
for(i=0;i<msg->total_hfields;i++) {
if(msg->hfield[i].type==RFC822HEADER) {
if(strnicmp((char*)msg->hfield_dat[i],"Content-Type:",13)==0) {
content_type=msg->hfield_dat[i];
break;
}
}
}
if(content_type == NULL) /* not MIME */
return NULL;
txt = mime_getcontent(buf, content_type, "text/plain", 0, &xfer_encoding
......@@ -442,21 +453,13 @@ char* SMBCALL smb_getplaintext(smbmsg_t* msg, char* buf)
}
/* Get just an attachment (just one) from MIME-encoded message body */
/* This function is destructive (over-writes 'buf' with decoded attachment)! */
uint8_t* SMBCALL smb_getattachment(smbmsg_t* msg, char* buf, char* filename, size_t filename_len, uint32_t* filelen, int index)
{
int i;
char* txt;
char* content_type = NULL;
char* content_type = smb_getcontenttype(msg);
enum content_transfer_encoding xfer_encoding = CONTENT_TRANFER_ENCODING_NONE;
for(i=0;i<msg->total_hfields;i++) {
if(msg->hfield[i].type==RFC822HEADER) {
if(strnicmp((char*)msg->hfield_dat[i],"Content-Type:",13)==0) {
content_type=msg->hfield_dat[i];
break;
}
}
}
if(content_type == NULL) /* not MIME */
return NULL;
txt = mime_getcontent(buf, content_type, /* match-type: */NULL, 0, &xfer_encoding
......@@ -466,9 +469,43 @@ uint8_t* SMBCALL smb_getattachment(smbmsg_t* msg, char* buf, char* filename, siz
int result = b64_decode(buf, strlen(buf), buf, strlen(buf));
if(result < 1)
return NULL;
*filelen = result;
if(filelen != NULL)
*filelen = result;
return (uint8_t*)buf;
}
return NULL; /* No attachment */
}
/* Return number of file attachments contained in MIME-encoded message body */
/* 'body' may be NULL if the body text is not already read/available */
ulong SMBCALL smb_countattachments(smb_t* smb, smbmsg_t* msg, const char* body)
{
char* content_type = smb_getcontenttype(msg);
if(content_type == NULL) /* not MIME */
return 0;
ulong count = 0;
char* buf;
if(body == NULL)
buf = smb_getmsgtxt(smb, msg, GETMSGTXT_ALL);
else
buf = strdup(body);
if(buf == NULL)
return 0;
char* tmp;
while((tmp = strdup(buf)) != NULL) {
uint8_t* attachment = smb_getattachment(msg, tmp, NULL, 0, NULL, count);
free(tmp);
if(attachment == NULL)
break;
count++;
}
free(buf);
return count;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment