aboutsummaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorDavid Bremner <bremner@debian.org>2019-02-17 07:30:33 -0400
committerDavid Bremner <bremner@debian.org>2019-02-17 07:30:33 -0400
commitf7130468d27c4f37d45e6aa60baacfc3329ccff4 (patch)
treef26a901f6e28185d60200c9111de30e1c15b4996 /compat
Import notmuch_0.28.2.orig.tar.gz
[dgit import orig notmuch_0.28.2.orig.tar.gz]
Diffstat (limited to 'compat')
-rw-r--r--compat/.gitignore1
-rw-r--r--compat/Makefile5
-rw-r--r--compat/Makefile.local28
-rw-r--r--compat/README21
-rw-r--r--compat/canonicalize_file_name.c18
-rw-r--r--compat/check_asctime.c11
-rw-r--r--compat/check_getpwuid.c11
-rw-r--r--compat/compat.h85
-rw-r--r--compat/function-attributes.h47
-rw-r--r--compat/gen_zlib_pc.c18
-rw-r--r--compat/getdelim.c133
-rw-r--r--compat/getline.c29
-rw-r--r--compat/have_canonicalize_file_name.c10
-rw-r--r--compat/have_d_type.c10
-rw-r--r--compat/have_getline.c13
-rw-r--r--compat/have_strcasestr.c10
-rw-r--r--compat/have_strsep.c11
-rw-r--r--compat/have_timegm.c6
-rw-r--r--compat/strcasestr.c40
-rw-r--r--compat/strsep.c65
-rw-r--r--compat/timegm.c56
21 files changed, 628 insertions, 0 deletions
diff --git a/compat/.gitignore b/compat/.gitignore
new file mode 100644
index 00000000..7ede45e9
--- /dev/null
+++ b/compat/.gitignore
@@ -0,0 +1 @@
+/zlib.pc
diff --git a/compat/Makefile b/compat/Makefile
new file mode 100644
index 00000000..fa25832e
--- /dev/null
+++ b/compat/Makefile
@@ -0,0 +1,5 @@
+all:
+ $(MAKE) -C .. all
+
+.DEFAULT:
+ $(MAKE) -C .. $@
diff --git a/compat/Makefile.local b/compat/Makefile.local
new file mode 100644
index 00000000..bcb9f0ec
--- /dev/null
+++ b/compat/Makefile.local
@@ -0,0 +1,28 @@
+# -*- makefile -*-
+
+dir := compat
+extra_cflags += -I$(srcdir)/$(dir)
+
+notmuch_compat_srcs :=
+
+ifneq ($(HAVE_CANONICALIZE_FILE_NAME),1)
+notmuch_compat_srcs += $(dir)/canonicalize_file_name.c
+endif
+
+ifneq ($(HAVE_GETLINE),1)
+notmuch_compat_srcs += $(dir)/getline.c $(dir)/getdelim.c
+endif
+
+ifneq ($(HAVE_STRCASESTR),1)
+notmuch_compat_srcs += $(dir)/strcasestr.c
+endif
+
+ifneq ($(HAVE_STRSEP),1)
+notmuch_compat_srcs += $(dir)/strsep.c
+endif
+
+ifneq ($(HAVE_TIMEGM),1)
+notmuch_compat_srcs += $(dir)/timegm.c
+endif
+
+SRCS := $(SRCS) $(notmuch_compat_srcs)
diff --git a/compat/README b/compat/README
new file mode 100644
index 00000000..12aacf42
--- /dev/null
+++ b/compat/README
@@ -0,0 +1,21 @@
+notmuch/compat
+
+This directory consists of three things:
+
+1. Small programs used by the notmuch configure script to test for the
+ availability of certain system features, (library functions, etc.).
+
+ For example: have_getline.c
+
+2. Compatibility implementations of those system features for systems
+ that don't provide their own versions.
+
+ For example: getline.c
+
+ The compilation of these files is made conditional on the output of
+ the test programs from [1].
+
+3. Macro definitions abstracting compiler differences (e.g. function
+ attributes).
+
+ For example: function-attributes.h
diff --git a/compat/canonicalize_file_name.c b/compat/canonicalize_file_name.c
new file mode 100644
index 00000000..e92c0f62
--- /dev/null
+++ b/compat/canonicalize_file_name.c
@@ -0,0 +1,18 @@
+#include "compat.h"
+#include <limits.h>
+#undef _GNU_SOURCE
+#include <stdlib.h>
+
+char *
+canonicalize_file_name (const char * path)
+{
+#ifdef PATH_MAX
+ char *resolved_path = malloc (PATH_MAX+1);
+ if (resolved_path == NULL)
+ return NULL;
+
+ return realpath (path, resolved_path);
+#else
+#error undefined PATH_MAX _and_ missing canonicalize_file_name not supported
+#endif
+}
diff --git a/compat/check_asctime.c b/compat/check_asctime.c
new file mode 100644
index 00000000..b0e56f0c
--- /dev/null
+++ b/compat/check_asctime.c
@@ -0,0 +1,11 @@
+#include <time.h>
+#include <stdio.h>
+
+int main()
+{
+ struct tm tm;
+
+ (void) asctime_r (&tm, NULL);
+
+ return (0);
+}
diff --git a/compat/check_getpwuid.c b/compat/check_getpwuid.c
new file mode 100644
index 00000000..c435eb89
--- /dev/null
+++ b/compat/check_getpwuid.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <pwd.h>
+
+int main()
+{
+ struct passwd passwd, *ignored;
+
+ (void) getpwuid_r (0, &passwd, NULL, 0, &ignored);
+
+ return (0);
+}
diff --git a/compat/compat.h b/compat/compat.h
new file mode 100644
index 00000000..88bc4df4
--- /dev/null
+++ b/compat/compat.h
@@ -0,0 +1,85 @@
+/* notmuch - Not much of an email library, (just index and search)
+ *
+ * Copyright © 2009 Carl Worth
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ *
+ * Author: Carl Worth <cworth@cworth.org>
+ */
+
+/* This header file defines functions that will only be conditionally
+ * compiled for compatibility on systems that don't provide their own
+ * implementations of the functions.
+ */
+
+#ifndef NOTMUCH_COMPAT_H
+#define NOTMUCH_COMPAT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !STD_GETPWUID
+#define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+#if !STD_ASCTIME
+#define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+
+#if !HAVE_CANONICALIZE_FILE_NAME
+/* we only call this function from C, and this makes testing easier */
+#ifndef __cplusplus
+char *
+canonicalize_file_name (const char *path);
+#endif
+#endif
+
+#if !HAVE_GETLINE
+#include <stdio.h>
+#include <unistd.h>
+
+ssize_t
+getline (char **lineptr, size_t *n, FILE *stream);
+
+ssize_t
+getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp);
+
+#endif /* !HAVE_GETLINE */
+
+#if !HAVE_STRCASESTR
+char* strcasestr(const char *haystack, const char *needle);
+#endif /* !HAVE_STRCASESTR */
+
+#if !HAVE_STRSEP
+char *strsep(char **stringp, const char *delim);
+#endif /* !HAVE_STRSEP */
+
+#if !HAVE_TIMEGM
+#include <time.h>
+time_t timegm (struct tm *tm);
+#endif /* !HAVE_TIMEGM */
+
+/* Silence gcc warnings about unused results. These warnings exist
+ * for a reason; any use of this needs to be justified. */
+#ifdef __GNUC__
+#define IGNORE_RESULT(x) ({ __typeof__(x) __z = (x); (void)(__z = __z); })
+#else /* !__GNUC__ */
+#define IGNORE_RESULT(x) x
+#endif /* __GNUC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NOTMUCH_COMPAT_H */
diff --git a/compat/function-attributes.h b/compat/function-attributes.h
new file mode 100644
index 00000000..1945b5bf
--- /dev/null
+++ b/compat/function-attributes.h
@@ -0,0 +1,47 @@
+/* function-attributes.h - Provides compiler abstractions for
+ * function attributes
+ *
+ * Copyright (c) 2012 Justus Winter <4winter@informatik.uni-hamburg.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ */
+
+#ifndef FUNCTION_ATTRIBUTES_H
+#define FUNCTION_ATTRIBUTES_H
+
+/* clang provides this macro to test for support for function
+ * attributes. If it isn't defined, this provides a compatibility
+ * macro for other compilers.
+ */
+#ifndef __has_attribute
+#define __has_attribute(x) 0
+#endif
+
+/* Provide a NORETURN_ATTRIBUTE macro similar to PRINTF_ATTRIBUTE from
+ * talloc.
+ *
+ * This attribute is understood by gcc since version 2.5. clang
+ * provides support for testing for function attributes.
+ */
+#ifndef NORETURN_ATTRIBUTE
+#if (__GNUC__ >= 3 || \
+ (__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || \
+ __has_attribute (noreturn))
+#define NORETURN_ATTRIBUTE __attribute__ ((noreturn))
+#else
+#define NORETURN_ATTRIBUTE
+#endif
+#endif
+
+#endif
diff --git a/compat/gen_zlib_pc.c b/compat/gen_zlib_pc.c
new file mode 100644
index 00000000..198a727c
--- /dev/null
+++ b/compat/gen_zlib_pc.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <zlib.h>
+
+static const char *template =
+ "prefix=/usr\n"
+ "exec_prefix=${prefix}\n"
+ "libdir=${exec_prefix}/lib\n"
+ "\n"
+ "Name: zlib\n"
+ "Description: zlib compression library\n"
+ "Version: %s\n"
+ "Libs: -lz\n";
+
+int main(void)
+{
+ printf(template, ZLIB_VERSION);
+ return 0;
+}
diff --git a/compat/getdelim.c b/compat/getdelim.c
new file mode 100644
index 00000000..407f3d07
--- /dev/null
+++ b/compat/getdelim.c
@@ -0,0 +1,133 @@
+/* getdelim.c --- Implementation of replacement getdelim function.
+ Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007,
+ 2008, 2009 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 3, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/* Ported from glibc by Simon Josefsson. */
+
+#include "compat.h"
+
+#include <stdio.h>
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#ifndef SSIZE_MAX
+# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
+#endif
+
+#if USE_UNLOCKED_IO
+# include "unlocked-io.h"
+# define getc_maybe_unlocked(fp) getc(fp)
+#elif !HAVE_FLOCKFILE || !HAVE_FUNLOCKFILE || !HAVE_DECL_GETC_UNLOCKED
+# undef flockfile
+# undef funlockfile
+# define flockfile(x) ((void) 0)
+# define funlockfile(x) ((void) 0)
+# define getc_maybe_unlocked(fp) getc(fp)
+#else
+# define getc_maybe_unlocked(fp) getc_unlocked(fp)
+#endif
+
+/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
+ NUL-terminate it). *LINEPTR is a pointer returned from malloc (or
+ NULL), pointing to *N characters of space. It is realloc'ed as
+ necessary. Returns the number of characters read (not including
+ the null terminator), or -1 on error or EOF. */
+
+ssize_t
+getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
+{
+ ssize_t result = -1;
+ size_t cur_len = 0;
+
+ if (lineptr == NULL || n == NULL || fp == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ flockfile (fp);
+
+ if (*lineptr == NULL || *n == 0)
+ {
+ char *new_lineptr;
+ *n = 120;
+ new_lineptr = (char *) realloc (*lineptr, *n);
+ if (new_lineptr == NULL)
+ {
+ result = -1;
+ goto unlock_return;
+ }
+ *lineptr = new_lineptr;
+ }
+
+ for (;;)
+ {
+ int i;
+
+ i = getc_maybe_unlocked (fp);
+ if (i == EOF)
+ {
+ result = -1;
+ break;
+ }
+
+ /* Make enough space for len+1 (for final NUL) bytes. */
+ if (cur_len + 1 >= *n)
+ {
+ size_t needed_max =
+ SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
+ size_t needed = 2 * *n + 1; /* Be generous. */
+ char *new_lineptr;
+
+ if (needed_max < needed)
+ needed = needed_max;
+ if (cur_len + 1 >= needed)
+ {
+ result = -1;
+ errno = EOVERFLOW;
+ goto unlock_return;
+ }
+
+ new_lineptr = (char *) realloc (*lineptr, needed);
+ if (new_lineptr == NULL)
+ {
+ result = -1;
+ goto unlock_return;
+ }
+
+ *lineptr = new_lineptr;
+ *n = needed;
+ }
+
+ (*lineptr)[cur_len] = i;
+ cur_len++;
+
+ if (i == delimiter)
+ break;
+ }
+ (*lineptr)[cur_len] = '\0';
+ result = cur_len ? (ssize_t) cur_len : result;
+
+ unlock_return:
+ funlockfile (fp); /* doesn't set errno */
+
+ return result;
+}
diff --git a/compat/getline.c b/compat/getline.c
new file mode 100644
index 00000000..222e0f6c
--- /dev/null
+++ b/compat/getline.c
@@ -0,0 +1,29 @@
+/* getline.c --- Implementation of replacement getline function.
+ Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 3, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/* Written by Simon Josefsson. */
+
+#include "compat.h"
+
+#include <stdio.h>
+
+ssize_t
+getline (char **lineptr, size_t *n, FILE *stream)
+{
+ return getdelim (lineptr, n, '\n', stream);
+}
diff --git a/compat/have_canonicalize_file_name.c b/compat/have_canonicalize_file_name.c
new file mode 100644
index 00000000..24c848ec
--- /dev/null
+++ b/compat/have_canonicalize_file_name.c
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+
+int main()
+{
+ char *found;
+ char *string;
+
+ found = canonicalize_file_name (string);
+}
diff --git a/compat/have_d_type.c b/compat/have_d_type.c
new file mode 100644
index 00000000..9ca6c6e0
--- /dev/null
+++ b/compat/have_d_type.c
@@ -0,0 +1,10 @@
+#include <dirent.h>
+
+int main()
+{
+ struct dirent ent;
+
+ (void) ent.d_type;
+
+ return 0;
+}
diff --git a/compat/have_getline.c b/compat/have_getline.c
new file mode 100644
index 00000000..a8bcd17e
--- /dev/null
+++ b/compat/have_getline.c
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <sys/types.h>
+
+int main()
+{
+ ssize_t count = 0;
+ size_t n = 0;
+ char **lineptr = NULL;
+ FILE *stream = NULL;
+
+ count = getline(lineptr, &n, stream);
+}
diff --git a/compat/have_strcasestr.c b/compat/have_strcasestr.c
new file mode 100644
index 00000000..c0fb7629
--- /dev/null
+++ b/compat/have_strcasestr.c
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE
+#include <strings.h>
+
+int main()
+{
+ char *found;
+ const char *haystack, *needle;
+
+ found = strcasestr(haystack, needle);
+}
diff --git a/compat/have_strsep.c b/compat/have_strsep.c
new file mode 100644
index 00000000..2abab819
--- /dev/null
+++ b/compat/have_strsep.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include <string.h>
+
+int main()
+{
+ char *found;
+ char **stringp;
+ const char *delim;
+
+ found = strsep(stringp, delim);
+}
diff --git a/compat/have_timegm.c b/compat/have_timegm.c
new file mode 100644
index 00000000..483fc3b6
--- /dev/null
+++ b/compat/have_timegm.c
@@ -0,0 +1,6 @@
+#include <time.h>
+
+int main()
+{
+ return (int) timegm((struct tm *)0);
+}
diff --git a/compat/strcasestr.c b/compat/strcasestr.c
new file mode 100644
index 00000000..62a3a545
--- /dev/null
+++ b/compat/strcasestr.c
@@ -0,0 +1,40 @@
+/*
+ * slow simplistic reimplementation of strcasestr for systems that
+ * don't include it in their library
+ *
+ * based on a GPL implementation in OpenTTD found under GPL v2
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, version 2.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/* Imported into notmuch by Dirk Hohndel - original author unknown. */
+
+#include <string.h>
+
+#include "compat.h"
+
+char *strcasestr(const char *haystack, const char *needle)
+{
+ size_t hay_len = strlen(haystack);
+ size_t needle_len = strlen(needle);
+ while (hay_len >= needle_len) {
+ if (strncasecmp(haystack, needle, needle_len) == 0)
+ return (char *) haystack;
+
+ haystack++;
+ hay_len--;
+ }
+
+ return NULL;
+}
diff --git a/compat/strsep.c b/compat/strsep.c
new file mode 100644
index 00000000..78ab9e71
--- /dev/null
+++ b/compat/strsep.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1992, 93, 96, 97, 98, 99, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+
+/* Taken from glibc 2.6.1 */
+
+char *strsep (char **stringp, const char *delim)
+{
+ char *begin, *end;
+
+ begin = *stringp;
+ if (begin == NULL)
+ return NULL;
+
+ /* A frequent case is when the delimiter string contains only one
+ character. Here we don't need to call the expensive `strpbrk'
+ function and instead work using `strchr'. */
+ if (delim[0] == '\0' || delim[1] == '\0')
+ {
+ char ch = delim[0];
+
+ if (ch == '\0')
+ end = NULL;
+ else
+ {
+ if (*begin == ch)
+ end = begin;
+ else if (*begin == '\0')
+ end = NULL;
+ else
+ end = strchr (begin + 1, ch);
+ }
+ }
+ else
+ /* Find the end of the token. */
+ end = strpbrk (begin, delim);
+
+ if (end)
+ {
+ /* Terminate the token and set *STRINGP past NUL character. */
+ *end++ = '\0';
+ *stringp = end;
+ }
+ else
+ /* No more delimiters; this is the last token. */
+ *stringp = NULL;
+
+ return begin;
+}
diff --git a/compat/timegm.c b/compat/timegm.c
new file mode 100644
index 00000000..3560c370
--- /dev/null
+++ b/compat/timegm.c
@@ -0,0 +1,56 @@
+/* timegm.c --- Implementation of replacement timegm function.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 3, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/* Copyright 2013 Blake Jones. */
+
+#include <time.h>
+#include "compat.h"
+
+static int
+leapyear (int year)
+{
+ return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0));
+}
+
+/*
+ * This is a simple implementation of timegm() which does what is needed
+ * by create_output() -- just turns the "struct tm" into a GMT time_t.
+ * It does not normalize any of the fields of the "struct tm", nor does
+ * it set tm_wday or tm_yday.
+ */
+time_t
+timegm (struct tm *tm)
+{
+ int monthlen[2][12] = {
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ };
+ int year, month, days;
+
+ days = 365 * (tm->tm_year - 70);
+ for (year = 70; year < tm->tm_year; year++) {
+ if (leapyear(1900 + year)) {
+ days++;
+ }
+ }
+ for (month = 0; month < tm->tm_mon; month++) {
+ days += monthlen[leapyear(1900 + year)][month];
+ }
+ days += tm->tm_mday - 1;
+
+ return ((((days * 24) + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec);
+}