+/*
+ * URL
+ */
+
+static int
+InitURL (CT ct)
+{
+ return init_encoding (ct, openURL);
+}
+
+
+static int
+openURL (CT ct, char **file)
+{
+ struct exbody *e = ct->c_ctexbody;
+ CE ce = &ct->c_cefile;
+ char *urlprog, *program;
+ char buffer[BUFSIZ], cachefile[BUFSIZ];
+ int fd, caching, cachetype;
+ struct msgs_array args = { 0, 0, NULL};
+ pid_t child_id;
+
+ if ((urlprog = context_find(nmhaccessurl)) && *urlprog == '\0')
+ urlprog = NULL;
+
+ if (! urlprog) {
+ content_error(NULL, ct, "No entry for nmh-access-url in profile");
+ return NOTOK;
+ }
+
+ switch (openExternal(e->eb_parent, e->eb_content, ce, file, &fd)) {
+ case NOTOK:
+ return NOTOK;
+
+ case OK:
+ break;
+
+ case DONE:
+ return fd;
+ }
+
+ if (!e->eb_url) {
+ content_error(NULL, ct, "missing url parameter");
+ return NOTOK;
+ }
+
+ if (xpid) {
+ if (xpid < 0)
+ xpid = -xpid;
+ pidcheck (pidwait (xpid, NOTOK));
+ xpid = 0;
+ }
+
+ ce->ce_unlink = (*file == NULL);
+ caching = 0;
+ cachefile[0] = '\0';
+
+ if (find_cache(NULL, wcachesw, &cachetype, e->eb_content->c_id,
+ cachefile, sizeof(cachefile)) != NOTOK) {
+ if (*file == NULL) {
+ ce->ce_unlink = 0;
+ caching = 1;
+ }
+ }
+
+ if (*file)
+ ce->ce_file = add(*file, NULL);
+ else if (caching)
+ ce->ce_file = add(cachefile, NULL);
+ else
+ ce->ce_file = add(m_mktemp(tmp, NULL, NULL), NULL);
+
+ if ((ce->ce_fp = fopen(ce->ce_file, "w+")) == NULL) {
+ content_error(ce->ce_file, ct, "unable to fopen for read/writing");
+ return NOTOK;
+ }
+
+ switch (child_id = fork()) {
+ case NOTOK:
+ adios ("fork", "unable to");
+ /* NOTREACHED */
+
+ case OK:
+ argsplit_msgarg(&args, urlprog, &program);
+ app_msgarg(&args, e->eb_url);
+ app_msgarg(&args, NULL);
+ dup2(fileno(ce->ce_fp), 1);
+ close(fileno(ce->ce_fp));
+ execvp(program, args.msgs);
+ fprintf(stderr, "Unable to exec ");
+ perror(program);
+ _exit(-1);
+ /* NOTREACHED */
+
+ default:
+ if (pidXwait(child_id, NULL)) {
+ ce->ce_unlink = 1;
+ return NOTOK;
+ }
+ }
+
+ if (cachefile[0]) {
+ if (caching)
+ chmod(cachefile, cachetype ? m_gmprot() : 0444);
+ else {
+ int mask;
+ FILE *fp;
+
+ mask = umask (cachetype ? ~m_gmprot() : 0222);
+ if ((fp = fopen(cachefile, "w"))) {
+ int cc;
+ FILE *gp = ce->ce_fp;
+
+ fseeko(gp, 0, SEEK_SET);
+
+ while ((cc = fread(buffer, sizeof(*buffer),
+ sizeof(buffer), gp)) > 0)
+ fwrite(buffer, sizeof(*buffer), cc, fp);
+
+ fflush(fp);
+
+ if (ferror(gp)) {
+ admonish(ce->ce_file, "error reading");
+ unlink(cachefile);
+ }
+ }
+ umask(mask);
+ }
+ }
+
+ fseeko(ce->ce_fp, 0, SEEK_SET);
+ *file = ce->ce_file;
+ return fd;
+}
+