b7e56c
From 27998dc1340a2879a619225bbe43e952c858ef7e Mon Sep 17 00:00:00 2001
b7e56c
From: Bastien Nocera <hadess@hadess.net>
b7e56c
Date: Mon, 4 Jun 2018 14:25:29 +0200
b7e56c
Subject: [PATCH] Remove gmime dependency
b7e56c
b7e56c
---
b7e56c
 meson.build                           |  21 +-
b7e56c
 plparse/meson.build                   |   1 +
b7e56c
 plparse/totem-pl-parser-decode-date.c | 608 ++++++++++++++++++++++++++
b7e56c
 plparse/totem-pl-parser-decode-date.h |  25 ++
b7e56c
 plparse/totem-pl-parser.c             |   5 +-
b7e56c
 5 files changed, 641 insertions(+), 19 deletions(-)
b7e56c
 create mode 100644 plparse/totem-pl-parser-decode-date.c
b7e56c
 create mode 100644 plparse/totem-pl-parser-decode-date.h
b7e56c
b7e56c
diff --git a/meson.build b/meson.build
b7e56c
index 1c126c5..bad7351 100644
b7e56c
--- a/meson.build
b7e56c
+++ b/meson.build
b7e56c
@@ -137,25 +137,16 @@ foreach cflag: test_cflags
b7e56c
 endforeach
b7e56c
 
b7e56c
 # gmime dependency
b7e56c
-enable_gmime = not get_option('disable-gmime-i-know-what-im-doing')
b7e56c
+enable_gmime = true
b7e56c
 if enable_gmime
b7e56c
-   have_gmime3 = false
b7e56c
-   gmime_dep = dependency('gmime-3.0', required : false)
b7e56c
-   if gmime_dep.found()
b7e56c
-     cdata.set('HAVE_GMIME3', true,
b7e56c
-       description: 'GMime 3.0 available in the system')
b7e56c
-     pkgconf.set('GMIME', 'gmime-3.0')
b7e56c
-   else
b7e56c
-     gmime_dep = dependency('gmime-2.6', required : false)
b7e56c
-     if not gmime_dep.found()
b7e56c
-       error('libgmime is required to compile totem-pl-parser.')
b7e56c
-     endif
b7e56c
-     pkgconf.set('GMIME', 'gmime-2.6')
b7e56c
-   endif
b7e56c
    pkgconf.set('USEGMIME', 'yes')
b7e56c
    cdata.set('HAVE_GMIME', true,
b7e56c
      description: 'GMime available in the system')
b7e56c
-   totem_pl_parser_deps += [gmime_dep]
b7e56c
+   pkgconf.set('GMIME', '')
b7e56c
+   cdata.set('HAVE_TM_GMTOFF', true,
b7e56c
+     description: 'Whether struct tm has a tm_gmtoff member')
b7e56c
+   cdata.set('HAVE_TIMEZONE', true,
b7e56c
+     description: 'Whether libc defines a timezone variable')
b7e56c
 else
b7e56c
   message('''
b7e56c
 **************************************************************
b7e56c
diff --git a/plparse/meson.build b/plparse/meson.build
b7e56c
index bbc3757..48b0556 100644
b7e56c
--- a/plparse/meson.build
b7e56c
+++ b/plparse/meson.build
b7e56c
@@ -34,6 +34,7 @@ plparser_sources = [
b7e56c
   'totem-disc.c',
b7e56c
   'totem-pl-parser.c',
b7e56c
   'totem-pl-parser-amz.c',
b7e56c
+  'totem-pl-parser-decode-date.c',
b7e56c
   'totem-pl-parser-lines.c',
b7e56c
   'totem-pl-parser-media.c',
b7e56c
   'totem-pl-parser-misc.c',
b7e56c
diff --git a/plparse/totem-pl-parser-decode-date.c b/plparse/totem-pl-parser-decode-date.c
b7e56c
new file mode 100644
b7e56c
index 0000000..aefefd1
b7e56c
--- /dev/null
b7e56c
+++ b/plparse/totem-pl-parser-decode-date.c
b7e56c
@@ -0,0 +1,608 @@
b7e56c
+/*  GMime
b7e56c
+ *  Copyright (C) 2000-2009 Jeffrey Stedfast
b7e56c
+ *
b7e56c
+ *  This library is free software; you can redistribute it and/or
b7e56c
+ *  modify it under the terms of the GNU Lesser General Public License
b7e56c
+ *  as published by the Free Software Foundation; either version 2.1
b7e56c
+ *  of the License, or (at your option) any later version.
b7e56c
+ *
b7e56c
+ *  This library is distributed in the hope that it will be useful,
b7e56c
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
b7e56c
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
b7e56c
+ *  Lesser General Public License for more details.
b7e56c
+ *
b7e56c
+ *  You should have received a copy of the GNU Lesser General Public
b7e56c
+ *  License along with this library; if not, write to the Free
b7e56c
+ *  Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
b7e56c
+ *  02110-1301, USA.
b7e56c
+ */
b7e56c
+
b7e56c
+#include "config.h"
b7e56c
+
b7e56c
+#include <glib.h>
b7e56c
+
b7e56c
+#include <stdio.h>
b7e56c
+#include <stdlib.h>
b7e56c
+#include <string.h>
b7e56c
+
b7e56c
+#include "totem-pl-parser-decode-date.h"
b7e56c
+
b7e56c
+#define d(x)
b7e56c
+
b7e56c
+#define DATE_TOKEN_NON_NUMERIC          (1 << 0)
b7e56c
+#define DATE_TOKEN_NON_WEEKDAY          (1 << 1)
b7e56c
+#define DATE_TOKEN_NON_MONTH            (1 << 2)
b7e56c
+#define DATE_TOKEN_NON_TIME             (1 << 3)
b7e56c
+#define DATE_TOKEN_HAS_COLON            (1 << 4)
b7e56c
+#define DATE_TOKEN_NON_TIMEZONE_ALPHA   (1 << 5)
b7e56c
+#define DATE_TOKEN_NON_TIMEZONE_NUMERIC (1 << 6)
b7e56c
+#define DATE_TOKEN_HAS_SIGN             (1 << 7)
b7e56c
+
b7e56c
+static unsigned char gmime_datetok_table[256] = {
b7e56c
+	128,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
b7e56c
+	111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
b7e56c
+	111,111,111,111,111,111,111,111, 79, 79,111,175,111,175,111,111,
b7e56c
+	 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,119,111,111,111,111,111,
b7e56c
+	111, 75,111, 79, 75, 79,105, 79,111,111,107,111,111, 73, 75,107,
b7e56c
+	 79,111,111, 73, 77, 79,111,109,111, 79, 79,111,111,111,111,111,
b7e56c
+	111,105,107,107,109,105,111,107,105,105,111,111,107,107,105,105,
b7e56c
+	107,111,105,105,105,105,107,111,111,105,111,111,111,111,111,111,
b7e56c
+	111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
b7e56c
+	111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
b7e56c
+	111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
b7e56c
+	111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
b7e56c
+	111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
b7e56c
+	111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
b7e56c
+	111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
b7e56c
+	111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
b7e56c
+};
b7e56c
+
b7e56c
+/* hrm, is there a library for this shit? */
b7e56c
+static struct {
b7e56c
+	char *name;
b7e56c
+	int offset;
b7e56c
+} tz_offsets [] = {
b7e56c
+	{ "UT", 0 },
b7e56c
+	{ "GMT", 0 },
b7e56c
+	{ "EST", -500 },	/* these are all US timezones.  bloody yanks */
b7e56c
+	{ "EDT", -400 },
b7e56c
+	{ "CST", -600 },
b7e56c
+	{ "CDT", -500 },
b7e56c
+	{ "MST", -700 },
b7e56c
+	{ "MDT", -600 },
b7e56c
+	{ "PST", -800 },
b7e56c
+	{ "PDT", -700 },
b7e56c
+	{ "Z", 0 },
b7e56c
+	{ "A", -100 },
b7e56c
+	{ "M", -1200 },
b7e56c
+	{ "N", 100 },
b7e56c
+	{ "Y", 1200 },
b7e56c
+};
b7e56c
+
b7e56c
+static char *tm_months[] = {
b7e56c
+	"Jan", "Feb", "Mar", "Apr", "May", "Jun",
b7e56c
+	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
b7e56c
+};
b7e56c
+
b7e56c
+static char *tm_days[] = {
b7e56c
+	"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
b7e56c
+};
b7e56c
+
b7e56c
+/* This is where it gets ugly... */
b7e56c
+
b7e56c
+typedef struct _date_token {
b7e56c
+	struct _date_token *next;
b7e56c
+	unsigned char mask;
b7e56c
+	const char *start;
b7e56c
+	size_t len;
b7e56c
+} date_token;
b7e56c
+
b7e56c
+#define date_token_free(tok) g_slice_free (date_token, tok)
b7e56c
+#define date_token_new() g_slice_new (date_token)
b7e56c
+
b7e56c
+static date_token *
b7e56c
+datetok (const char *date)
b7e56c
+{
b7e56c
+	date_token *tokens = NULL, *token, *tail = (date_token *) &tokens;
b7e56c
+	const char *start, *end;
b7e56c
+        unsigned char mask;
b7e56c
+	
b7e56c
+	start = date;
b7e56c
+	while (*start) {
b7e56c
+		/* kill leading whitespace */
b7e56c
+		while (*start == ' ' || *start == '\t')
b7e56c
+			start++;
b7e56c
+		
b7e56c
+		if (*start == '\0')
b7e56c
+			break;
b7e56c
+		
b7e56c
+		mask = gmime_datetok_table[(unsigned char) *start];
b7e56c
+		
b7e56c
+		/* find the end of this token */
b7e56c
+		end = start + 1;
b7e56c
+		while (*end && !strchr ("-/,\t\r\n ", *end))
b7e56c
+			mask |= gmime_datetok_table[(unsigned char) *end++];
b7e56c
+		
b7e56c
+		if (end != start) {
b7e56c
+			token = date_token_new ();
b7e56c
+			token->next = NULL;
b7e56c
+			token->start = start;
b7e56c
+			token->len = end - start;
b7e56c
+			token->mask = mask;
b7e56c
+			
b7e56c
+			tail->next = token;
b7e56c
+			tail = token;
b7e56c
+		}
b7e56c
+		
b7e56c
+		if (*end)
b7e56c
+			start = end + 1;
b7e56c
+		else
b7e56c
+			break;
b7e56c
+	}
b7e56c
+	
b7e56c
+	return tokens;
b7e56c
+}
b7e56c
+
b7e56c
+static int
b7e56c
+decode_int (const char *in, size_t inlen)
b7e56c
+{
b7e56c
+	register const char *inptr;
b7e56c
+	int sign = 1, val = 0;
b7e56c
+	const char *inend;
b7e56c
+	
b7e56c
+	inptr = in;
b7e56c
+	inend = in + inlen;
b7e56c
+	
b7e56c
+	if (*inptr == '-') {
b7e56c
+		sign = -1;
b7e56c
+		inptr++;
b7e56c
+	} else if (*inptr == '+')
b7e56c
+		inptr++;
b7e56c
+	
b7e56c
+	for ( ; inptr < inend; inptr++) {
b7e56c
+		if (!(*inptr >= '0' && *inptr <= '9'))
b7e56c
+			return -1;
b7e56c
+		else
b7e56c
+			val = (val * 10) + (*inptr - '0');
b7e56c
+	}
b7e56c
+	
b7e56c
+	val *= sign;
b7e56c
+	
b7e56c
+	return val;
b7e56c
+}
b7e56c
+
b7e56c
+#if 0
b7e56c
+static int
b7e56c
+get_days_in_month (int month, int year)
b7e56c
+{
b7e56c
+        switch (month) {
b7e56c
+	case 1:
b7e56c
+	case 3:
b7e56c
+	case 5:
b7e56c
+	case 7:
b7e56c
+	case 8:
b7e56c
+	case 10:
b7e56c
+	case 12:
b7e56c
+	        return 31;
b7e56c
+	case 4:
b7e56c
+	case 6:
b7e56c
+	case 9:
b7e56c
+	case 11:
b7e56c
+	        return 30;
b7e56c
+	case 2:
b7e56c
+	        if (g_date_is_leap_year (year))
b7e56c
+		        return 29;
b7e56c
+		else
b7e56c
+		        return 28;
b7e56c
+	default:
b7e56c
+	        return 0;
b7e56c
+	}
b7e56c
+}
b7e56c
+#endif
b7e56c
+
b7e56c
+static int
b7e56c
+get_wday (const char *in, size_t inlen)
b7e56c
+{
b7e56c
+	int wday;
b7e56c
+	
b7e56c
+	g_return_val_if_fail (in != NULL, -1);
b7e56c
+	
b7e56c
+	if (inlen < 3)
b7e56c
+		return -1;
b7e56c
+	
b7e56c
+	for (wday = 0; wday < 7; wday++) {
b7e56c
+		if (!g_ascii_strncasecmp (in, tm_days[wday], 3))
b7e56c
+			return wday;
b7e56c
+	}
b7e56c
+	
b7e56c
+	return -1;  /* unknown week day */
b7e56c
+}
b7e56c
+
b7e56c
+static int
b7e56c
+get_mday (const char *in, size_t inlen)
b7e56c
+{
b7e56c
+	int mday;
b7e56c
+	
b7e56c
+	g_return_val_if_fail (in != NULL, -1);
b7e56c
+	
b7e56c
+	mday = decode_int (in, inlen);
b7e56c
+	
b7e56c
+	if (mday < 0 || mday > 31)
b7e56c
+		mday = -1;
b7e56c
+	
b7e56c
+	return mday;
b7e56c
+}
b7e56c
+
b7e56c
+static int
b7e56c
+get_month (const char *in, size_t inlen)
b7e56c
+{
b7e56c
+	int i;
b7e56c
+	
b7e56c
+	g_return_val_if_fail (in != NULL, -1);
b7e56c
+	
b7e56c
+	if (inlen < 3)
b7e56c
+		return -1;
b7e56c
+	
b7e56c
+	for (i = 0; i < 12; i++) {
b7e56c
+		if (!g_ascii_strncasecmp (in, tm_months[i], 3))
b7e56c
+			return i;
b7e56c
+	}
b7e56c
+	
b7e56c
+	return -1;  /* unknown month */
b7e56c
+}
b7e56c
+
b7e56c
+static int
b7e56c
+get_year (const char *in, size_t inlen)
b7e56c
+{
b7e56c
+	int year;
b7e56c
+	
b7e56c
+	g_return_val_if_fail (in != NULL, -1);
b7e56c
+	
b7e56c
+	if ((year = decode_int (in, inlen)) == -1)
b7e56c
+		return -1;
b7e56c
+	
b7e56c
+	if (year < 100)
b7e56c
+		year += (year < 70) ? 2000 : 1900;
b7e56c
+	
b7e56c
+	if (year < 1969)
b7e56c
+		return -1;
b7e56c
+	
b7e56c
+	return year;
b7e56c
+}
b7e56c
+
b7e56c
+static gboolean
b7e56c
+get_time (const char *in, size_t inlen, int *hour, int *min, int *sec)
b7e56c
+{
b7e56c
+	register const char *inptr;
b7e56c
+	int *val, colons = 0;
b7e56c
+	const char *inend;
b7e56c
+	
b7e56c
+	*hour = *min = *sec = 0;
b7e56c
+	
b7e56c
+	inend = in + inlen;
b7e56c
+	val = hour;
b7e56c
+	for (inptr = in; inptr < inend; inptr++) {
b7e56c
+		if (*inptr == ':') {
b7e56c
+			colons++;
b7e56c
+			switch (colons) {
b7e56c
+			case 1:
b7e56c
+				val = min;
b7e56c
+				break;
b7e56c
+			case 2:
b7e56c
+				val = sec;
b7e56c
+				break;
b7e56c
+			default:
b7e56c
+				return FALSE;
b7e56c
+			}
b7e56c
+		} else if (!(*inptr >= '0' && *inptr <= '9'))
b7e56c
+			return FALSE;
b7e56c
+		else
b7e56c
+			*val = (*val * 10) + (*inptr - '0');
b7e56c
+	}
b7e56c
+	
b7e56c
+	return TRUE;
b7e56c
+}
b7e56c
+
b7e56c
+static int
b7e56c
+get_tzone (date_token **token)
b7e56c
+{
b7e56c
+	const char *inptr, *inend;
b7e56c
+	size_t inlen;
b7e56c
+	int i, t;
b7e56c
+	
b7e56c
+	for (i = 0; *token && i < 2; *token = (*token)->next, i++) {
b7e56c
+		inptr = (*token)->start;
b7e56c
+		inlen = (*token)->len;
b7e56c
+		inend = inptr + inlen;
b7e56c
+		
b7e56c
+		if (*inptr == '+' || *inptr == '-') {
b7e56c
+			return decode_int (inptr, inlen);
b7e56c
+		} else {
b7e56c
+			if (*inptr == '(') {
b7e56c
+				inptr++;
b7e56c
+				if (*(inend - 1) == ')')
b7e56c
+					inlen -= 2;
b7e56c
+				else
b7e56c
+					inlen--;
b7e56c
+			}
b7e56c
+			
b7e56c
+			for (t = 0; t < 15; t++) {
b7e56c
+				size_t len = strlen (tz_offsets[t].name);
b7e56c
+				
b7e56c
+				if (len != inlen)
b7e56c
+					continue;
b7e56c
+				
b7e56c
+				if (!strncmp (inptr, tz_offsets[t].name, len))
b7e56c
+					return tz_offsets[t].offset;
b7e56c
+			}
b7e56c
+		}
b7e56c
+	}
b7e56c
+	
b7e56c
+	return -1;
b7e56c
+}
b7e56c
+
b7e56c
+static time_t
b7e56c
+mktime_utc (struct tm *tm)
b7e56c
+{
b7e56c
+	time_t tt;
b7e56c
+	long tz;
b7e56c
+	
b7e56c
+	tm->tm_isdst = -1;
b7e56c
+	tt = mktime (tm);
b7e56c
+	
b7e56c
+#if defined (G_OS_WIN32)
b7e56c
+	_get_timezone (&tz;;
b7e56c
+	if (tm->tm_isdst > 0) {
b7e56c
+		int dst;
b7e56c
+		
b7e56c
+		_get_dstbias (&dst);
b7e56c
+		tz += dst;
b7e56c
+	}
b7e56c
+#elif defined (HAVE_TM_GMTOFF)
b7e56c
+	tz = -tm->tm_gmtoff;
b7e56c
+#elif defined (HAVE_TIMEZONE)
b7e56c
+	if (tm->tm_isdst > 0) {
b7e56c
+#if defined (HAVE_ALTZONE)
b7e56c
+		tz = altzone;
b7e56c
+#else /* !defined (HAVE_ALTZONE) */
b7e56c
+		tz = (timezone - 3600);
b7e56c
+#endif
b7e56c
+	} else {
b7e56c
+		tz = timezone;
b7e56c
+	}
b7e56c
+#elif defined (HAVE__TIMEZONE)
b7e56c
+	tz = _timezone;
b7e56c
+#else
b7e56c
+#error Neither HAVE_TIMEZONE nor HAVE_TM_GMTOFF defined. Rerun meson.
b7e56c
+#endif
b7e56c
+	
b7e56c
+	return tt - tz;
b7e56c
+}
b7e56c
+
b7e56c
+static time_t
b7e56c
+parse_rfc822_date (date_token *tokens, int *tzone)
b7e56c
+{
b7e56c
+	int hour, min, sec, offset, n;
b7e56c
+	date_token *token;
b7e56c
+	struct tm tm;
b7e56c
+	time_t t;
b7e56c
+	
b7e56c
+	g_return_val_if_fail (tokens != NULL, (time_t) 0);
b7e56c
+	
b7e56c
+	token = tokens;
b7e56c
+	
b7e56c
+	memset ((void *) &tm, 0, sizeof (struct tm));
b7e56c
+	
b7e56c
+	if ((n = get_wday (token->start, token->len)) != -1) {
b7e56c
+		/* not all dates may have this... */
b7e56c
+		tm.tm_wday = n;
b7e56c
+		token = token->next;
b7e56c
+	}
b7e56c
+	
b7e56c
+	/* get the mday */
b7e56c
+	if (!token || (n = get_mday (token->start, token->len)) == -1)
b7e56c
+		return (time_t) 0;
b7e56c
+	
b7e56c
+	tm.tm_mday = n;
b7e56c
+	token = token->next;
b7e56c
+	
b7e56c
+	/* get the month */
b7e56c
+	if (!token || (n = get_month (token->start, token->len)) == -1)
b7e56c
+		return (time_t) 0;
b7e56c
+	
b7e56c
+	tm.tm_mon = n;
b7e56c
+	token = token->next;
b7e56c
+	
b7e56c
+	/* get the year */
b7e56c
+	if (!token || (n = get_year (token->start, token->len)) == -1)
b7e56c
+		return (time_t) 0;
b7e56c
+	
b7e56c
+	tm.tm_year = n - 1900;
b7e56c
+	token = token->next;
b7e56c
+	
b7e56c
+	/* get the hour/min/sec */
b7e56c
+	if (!token || !get_time (token->start, token->len, &hour, &min, &sec))
b7e56c
+		return (time_t) 0;
b7e56c
+	
b7e56c
+	tm.tm_hour = hour;
b7e56c
+	tm.tm_min = min;
b7e56c
+	tm.tm_sec = sec;
b7e56c
+	token = token->next;
b7e56c
+	
b7e56c
+	/* get the timezone */
b7e56c
+	if (!token || (n = get_tzone (&token)) == -1) {
b7e56c
+		/* I guess we assume tz is GMT? */
b7e56c
+		offset = 0;
b7e56c
+	} else {
b7e56c
+		offset = n;
b7e56c
+	}
b7e56c
+	
b7e56c
+	t = mktime_utc (&tm;;
b7e56c
+	
b7e56c
+	/* t is now GMT of the time we want, but not offset by the timezone ... */
b7e56c
+	
b7e56c
+	/* this should convert the time to the GMT equiv time */
b7e56c
+	t -= ((offset / 100) * 60 * 60) + (offset % 100) * 60;
b7e56c
+	
b7e56c
+	if (tzone)
b7e56c
+		*tzone = offset;
b7e56c
+	
b7e56c
+	return t;
b7e56c
+}
b7e56c
+
b7e56c
+
b7e56c
+#define date_token_mask(t)  (((date_token *) t)->mask)
b7e56c
+#define is_numeric(t)       ((date_token_mask (t) & DATE_TOKEN_NON_NUMERIC) == 0)
b7e56c
+#define is_weekday(t)       ((date_token_mask (t) & DATE_TOKEN_NON_WEEKDAY) == 0)
b7e56c
+#define is_month(t)         ((date_token_mask (t) & DATE_TOKEN_NON_MONTH) == 0)
b7e56c
+#define is_time(t)          (((date_token_mask (t) & DATE_TOKEN_NON_TIME) == 0) && (date_token_mask (t) & DATE_TOKEN_HAS_COLON))
b7e56c
+#define is_tzone_alpha(t)   ((date_token_mask (t) & DATE_TOKEN_NON_TIMEZONE_ALPHA) == 0)
b7e56c
+#define is_tzone_numeric(t) (((date_token_mask (t) & DATE_TOKEN_NON_TIMEZONE_NUMERIC) == 0) && (date_token_mask (t) & DATE_TOKEN_HAS_SIGN))
b7e56c
+#define is_tzone(t)         (is_tzone_alpha (t) || is_tzone_numeric (t))
b7e56c
+
b7e56c
+static time_t
b7e56c
+parse_broken_date (date_token *tokens, int *tzone)
b7e56c
+{
b7e56c
+	gboolean got_wday, got_month, got_tzone;
b7e56c
+	int hour, min, sec, offset, n;
b7e56c
+	date_token *token;
b7e56c
+	struct tm tm;
b7e56c
+	time_t t;
b7e56c
+	
b7e56c
+	memset ((void *) &tm, 0, sizeof (struct tm));
b7e56c
+	got_wday = got_month = got_tzone = FALSE;
b7e56c
+	offset = 0;
b7e56c
+	
b7e56c
+	token = tokens;
b7e56c
+	while (token) {
b7e56c
+		if (is_weekday (token) && !got_wday) {
b7e56c
+			if ((n = get_wday (token->start, token->len)) != -1) {
b7e56c
+				d(printf ("weekday; "));
b7e56c
+				got_wday = TRUE;
b7e56c
+				tm.tm_wday = n;
b7e56c
+				goto next;
b7e56c
+			}
b7e56c
+		}
b7e56c
+		
b7e56c
+		if (is_month (token) && !got_month) {
b7e56c
+			if ((n = get_month (token->start, token->len)) != -1) {
b7e56c
+				d(printf ("month; "));
b7e56c
+				got_month = TRUE;
b7e56c
+				tm.tm_mon = n;
b7e56c
+				goto next;
b7e56c
+			}
b7e56c
+		}
b7e56c
+		
b7e56c
+		if (is_time (token) && !tm.tm_hour && !tm.tm_min && !tm.tm_sec) {
b7e56c
+			if (get_time (token->start, token->len, &hour, &min, &sec)) {
b7e56c
+				d(printf ("time; "));
b7e56c
+				tm.tm_hour = hour;
b7e56c
+				tm.tm_min = min;
b7e56c
+				tm.tm_sec = sec;
b7e56c
+				goto next;
b7e56c
+			}
b7e56c
+		}
b7e56c
+		
b7e56c
+		if (is_tzone (token) && !got_tzone) {
b7e56c
+			date_token *t = token;
b7e56c
+			
b7e56c
+			if ((n = get_tzone (&t)) != -1) {
b7e56c
+				d(printf ("tzone; "));
b7e56c
+				got_tzone = TRUE;
b7e56c
+				offset = n;
b7e56c
+				goto next;
b7e56c
+			}
b7e56c
+		}
b7e56c
+		
b7e56c
+		if (is_numeric (token)) {
b7e56c
+			if (token->len == 4 && !tm.tm_year) {
b7e56c
+				if ((n = get_year (token->start, token->len)) != -1) {
b7e56c
+					d(printf ("year; "));
b7e56c
+					tm.tm_year = n - 1900;
b7e56c
+					goto next;
b7e56c
+				}
b7e56c
+			} else {
b7e56c
+				/* Note: assumes MM-DD-YY ordering if '0 < MM < 12' holds true */
b7e56c
+				if (!got_month && token->next && is_numeric (token->next)) {
b7e56c
+					if ((n = decode_int (token->start, token->len)) > 12) {
b7e56c
+						goto mday;
b7e56c
+					} else if (n > 0) {
b7e56c
+						d(printf ("mon; "));
b7e56c
+						got_month = TRUE;
b7e56c
+						tm.tm_mon = n - 1;
b7e56c
+					}
b7e56c
+					goto next;
b7e56c
+				} else if (!tm.tm_mday && (n = get_mday (token->start, token->len)) != -1) {
b7e56c
+				mday:
b7e56c
+					d(printf ("mday; "));
b7e56c
+					tm.tm_mday = n;
b7e56c
+					goto next;
b7e56c
+				} else if (!tm.tm_year) {
b7e56c
+					if ((n = get_year (token->start, token->len)) != -1) {
b7e56c
+						d(printf ("2-digit year; "));
b7e56c
+						tm.tm_year = n - 1900;
b7e56c
+					}
b7e56c
+					goto next;
b7e56c
+				}
b7e56c
+			}
b7e56c
+		}
b7e56c
+		
b7e56c
+		d(printf ("???; "));
b7e56c
+		
b7e56c
+	next:
b7e56c
+		
b7e56c
+		token = token->next;
b7e56c
+	}
b7e56c
+	
b7e56c
+	d(printf ("\n"));
b7e56c
+	
b7e56c
+	t = mktime_utc (&tm;;
b7e56c
+	
b7e56c
+	/* t is now GMT of the time we want, but not offset by the timezone ... */
b7e56c
+	
b7e56c
+	/* this should convert the time to the GMT equiv time */
b7e56c
+	t -= ((offset / 100) * 60 * 60) + (offset % 100) * 60;
b7e56c
+	
b7e56c
+	if (tzone)
b7e56c
+		*tzone = offset;
b7e56c
+	
b7e56c
+	return t;
b7e56c
+}
b7e56c
+
b7e56c
+/**
b7e56c
+ * g_mime_utils_header_decode_date:
b7e56c
+ * @str: input date string
b7e56c
+ * @tz_offset: timezone offset
b7e56c
+ *
b7e56c
+ * Decodes the rfc822 date string and saves the GMT offset into
b7e56c
+ * @tz_offset if non-NULL.
b7e56c
+ *
b7e56c
+ * Returns: the time_t representation of the date string specified by
b7e56c
+ * @str or (time_t) %0 on error. If @tz_offset is non-NULL, the value
b7e56c
+ * of the timezone offset will be stored.
b7e56c
+ **/
b7e56c
+time_t
b7e56c
+g_mime_utils_header_decode_date (const char *str, int *tz_offset)
b7e56c
+{
b7e56c
+	date_token *token, *tokens;
b7e56c
+	time_t date;
b7e56c
+	
b7e56c
+	if (!(tokens = datetok (str))) {
b7e56c
+		if (tz_offset)
b7e56c
+			*tz_offset = 0;
b7e56c
+		
b7e56c
+		return (time_t) 0;
b7e56c
+	}
b7e56c
+	
b7e56c
+	if (!(date = parse_rfc822_date (tokens, tz_offset)))
b7e56c
+		date = parse_broken_date (tokens, tz_offset);
b7e56c
+	
b7e56c
+	/* cleanup */
b7e56c
+	while (tokens) {
b7e56c
+		token = tokens;
b7e56c
+		tokens = tokens->next;
b7e56c
+		date_token_free (token);
b7e56c
+	}
b7e56c
+	
b7e56c
+	return date;
b7e56c
+}
b7e56c
diff --git a/plparse/totem-pl-parser-decode-date.h b/plparse/totem-pl-parser-decode-date.h
b7e56c
new file mode 100644
b7e56c
index 0000000..f1a7725
b7e56c
--- /dev/null
b7e56c
+++ b/plparse/totem-pl-parser-decode-date.h
b7e56c
@@ -0,0 +1,25 @@
b7e56c
+/*  GMime
b7e56c
+ *  Copyright (C) 2000-2009 Jeffrey Stedfast
b7e56c
+ *
b7e56c
+ *  This library is free software; you can redistribute it and/or
b7e56c
+ *  modify it under the terms of the GNU Lesser General Public License
b7e56c
+ *  as published by the Free Software Foundation; either version 2.1
b7e56c
+ *  of the License, or (at your option) any later version.
b7e56c
+ *
b7e56c
+ *  This library is distributed in the hope that it will be useful,
b7e56c
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
b7e56c
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
b7e56c
+ *  Lesser General Public License for more details.
b7e56c
+ *
b7e56c
+ *  You should have received a copy of the GNU Lesser General Public
b7e56c
+ *  License along with this library; if not, write to the Free
b7e56c
+ *  Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
b7e56c
+ *  02110-1301, USA.
b7e56c
+ */
b7e56c
+
b7e56c
+#include <glib.h>
b7e56c
+
b7e56c
+#include <stdio.h>
b7e56c
+
b7e56c
+time_t g_mime_utils_header_decode_date (const char *str, int *tz_offset);
b7e56c
+
b7e56c
diff --git a/plparse/totem-pl-parser.c b/plparse/totem-pl-parser.c
b7e56c
index 505957a..83fafa1 100644
b7e56c
--- a/plparse/totem-pl-parser.c
b7e56c
+++ b/plparse/totem-pl-parser.c
b7e56c
@@ -132,16 +132,13 @@
b7e56c
 #ifndef TOTEM_PL_PARSER_MINI
b7e56c
 #include <gobject/gvaluecollector.h>
b7e56c
 
b7e56c
-#ifdef HAVE_GMIME
b7e56c
-#include <gmime/gmime-utils.h>
b7e56c
-#endif
b7e56c
-
b7e56c
 #include "totem-pl-parser.h"
b7e56c
 #include "totemplparser-marshal.h"
b7e56c
 #include "totem-disc.h"
b7e56c
 #endif /* !TOTEM_PL_PARSER_MINI */
b7e56c
 
b7e56c
 #include "totem-pl-parser-mini.h"
b7e56c
+#include "totem-pl-parser-decode-date.h"
b7e56c
 #include "totem-pl-parser-wm.h"
b7e56c
 #include "totem-pl-parser-qt.h"
b7e56c
 #include "totem-pl-parser-pls.h"
b7e56c
-- 
b7e56c
2.17.0
b7e56c