+ m.size = statbuf.st_size;
+ m.data = malloc(m.size);
+ if (m.data == NULL)
+ return tls_error(US"memory allocation failed", host, 0);
+ if (read(fd, m.data, m.size) != m.size)
+ return tls_error(US"TLS cache read failed", host, 0);
+ (void)close(fd);
+
+ ret = gnutls_rsa_params_import_pkcs1(rsa_params, &m, GNUTLS_X509_FMT_PEM);
+ if (ret < 0)
+ {
+ DEBUG(D_tls)
+ debug_printf("RSA params import failed: assume old-style cache file\n");
+ }
+ else
+ {
+ ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM);
+ if (ret < 0)
+ return tls_error(US"DH params import", host, ret);
+ DEBUG(D_tls) debug_printf("read RSA and D-H parameters from file\n");
+ }
+
+ free(m.data);
+ }
+
+/* If the file does not exist, fall through to compute new data and cache it.
+If there was any other opening error, it is serious. */
+
+else if (errno != ENOENT)
+ return tls_error(string_open_failed(errno, "%s for reading", filename),
+ host, 0);
+
+/* If ret < 0, either the cache file does not exist, or the data it contains
+is not useful. One particular case of this is when upgrading from an older
+release of Exim in which the data was stored in a different format. We don't
+try to be clever and support both formats; we just regenerate new data in this
+case. */
+
+if (ret < 0)
+ {
+ uschar tempfilename[sizeof(filename) + 10];