mhshow/mhstore: Removed support for retrieving message/external-body parts.
authormarkus schnalke <meillo@marmaro.de>
Thu, 12 Apr 2012 21:05:47 +0000 (23:05 +0200)
committermarkus schnalke <meillo@marmaro.de>
Thu, 12 Apr 2012 21:05:47 +0000 (23:05 +0200)
These tools won't download the contents automatically anymore. Instead,
they print the information needed to get the contents. If someone should
really receive one of those rare message/external-body messages, he can
do the job manually. We save nearly a thousand lines of code. That's worth
it!
(The profile entry `nmh-access-ftp' and sbr/ruserpass.c for reading
~/.netrc are gone now.)

15 files changed:
config/config.c
h/mh.h
h/mhparse.h
h/prototypes.h
man/mhlist.man1
man/mhshow.man1
man/mhstore.man1
sbr/Makefile.in
sbr/ruserpass.c [deleted file]
uip/mhbuild.c
uip/mhfree.c
uip/mhlistsbr.c
uip/mhparse.c
uip/mhshowsbr.c
uip/mhstore.c

index 70a9a40..1caea47 100644 (file)
@@ -94,9 +94,6 @@ char *nsequence = "Sequence-Negation";
 /* profile entries for storage locations */
 char *nmhstorage   = "nmh-storage";
 
-/* profile entry for external ftp access command */
-char *nmhaccessftp = "nmh-access-ftp";
-
 /* Default attachment header field name */
 char *attach_hdr = "Attach";
 
diff --git a/h/mh.h b/h/mh.h
index 14f42f4..9eed2d0 100644 (file)
--- a/h/mh.h
+++ b/h/mh.h
@@ -296,7 +296,6 @@ extern char *mhlreply;
 extern char *mimetypequery;
 extern char *mimetypequeryproc;
 extern char *msgprot;
-extern char *nmhaccessftp;
 extern char *nmhstorage;
 extern char *nsequence;
 extern char *profile;
index af9b8ca..2d88127 100644 (file)
@@ -101,7 +101,6 @@ struct Content {
 
        /* pointers to content-specific structures */
        void *c_ctparams;            /* content type specific data        */
-       struct exbody *c_ctexbody;   /* data for type message/external    */
 
        /* function pointers */
        InitFunc    c_ctinitfnx;     /* parse content body                */
@@ -210,24 +209,6 @@ struct partial {
        int pm_stored;
 };
 
-/* Structure for message/external */
-struct exbody {
-       CT eb_parent;        /* pointer to controlling content structure */
-       CT eb_content;       /* pointer to internal content structure    */
-       char *eb_partno;
-       char *eb_access;
-       int eb_flags;
-       char *eb_name;
-       char *eb_permission;
-       char *eb_site;
-       char *eb_dir;
-       char *eb_mode;
-       unsigned long eb_size;
-       char *eb_server;
-       char *eb_subject;
-       char *eb_body;
-};
-
 /*
 ** APPLICATION content
 */
@@ -262,7 +243,6 @@ struct str2init {
 };
 extern struct str2init str2cts[];
 extern struct str2init str2ces[];
-extern struct str2init str2methods[];
 
 /*
 ** prototypes
@@ -271,6 +251,5 @@ int pidcheck(int);
 CT parse_mime(char *);
 int add_header(CT, char *, char *);
 int get_ctinfo(unsigned char *, CT, int);
-int params_external(CT, int);
 int open7Bit(CT, char **);
 void close_encoding(CT);
index ba33a03..f2c4652 100644 (file)
@@ -85,7 +85,6 @@ void push(void);
 char *pwd(void);
 char *mhbasename(char *);
 void readconfig(struct node **, FILE *, char *, int);
-void ruserpass(char *, char **, char **);
 int seq_addmsg(struct msgs *, char *, int, int, int);
 int seq_addsel(struct msgs *, char *, int, int);
 char *seq_bits(struct msgs *);
index b9b098c..f42498b 100644 (file)
@@ -129,14 +129,6 @@ Note that regardless of the values given to the
 .B \-type
 switch, a
 multipart content (of any subtype listed above) is always acted upon.
-Further note that if the
-.B \-type
-switch is used, and it is desirable to
-act on a message/external-body content, then the
-.B \-type
-switch must
-be used twice: once for message/external-body and once for the content
-externally referenced.
 
 .SH FILES
 .fc ^ ~
index 8ebc7ba..9b6465d 100644 (file)
@@ -111,10 +111,6 @@ name of the content, e.g., \*(lqaudio\*(rq.  To specify a specific
 subtype, separate the two with a slash, e.g., \*(lqaudio/basic\*(rq.
 Note that regardless of the values given to the `\-type' switch, a
 multipart content (of any subtype listed above) is always acted upon.
-Further note that if the `\-type' switch is used, and it is desirable to
-act on a message/external-body content, then the `\-type' switch must
-be used twice: once for message/external-body and once for the content
-externally referenced.
 .SS "Unseen Sequence"
 If the profile entry \*(lqUnseen\-Sequence\*(rq is present and
 non\-empty, then
@@ -388,48 +384,10 @@ Check the man page for
 .BR mhstore (1)
 for details.
 .SS "External Access"
-For contents of type message/external-body,
-.B mhshow
-supports these access-types:
-.PP
-.IP \(bu 4
-afs
-.IP \(bu 4
-anon-ftp
-.IP \(bu 4
-ftp
-.IP \(bu 4
-local-file
-.IP \(bu 4
-mail-server
-.PP
-For the \*(lqanon-ftp\*(rq and \*(lqftp\*(rq access types,
-.B mhshow
-will look for the \*(lqnmh-access-ftp\*(rq
-profile entry, e.g.,
-.PP
-.RS 5
-nmh-access-ftp: myftp.sh
-.RE
-.PP
-to determine the pathname of a program to perform the FTP retrieval.
-.PP
-This program is invoked with these arguments:
-.PP
-.RS 5
-.nf
-domain name of FTP-site
-username
-password
-remote directory
-remote filename
-local filename
-\*(lqascii\*(rq or \*(lqbinary\*(rq
-.fi
-.RE
-.PP
-The program should terminate with an exit status of zero if the
-retrieval is successful, and a non-zero exit status otherwise.
+.B Mhshow
+does not automatically retrieve message/external-body parts (anymore),
+but prints the relevant information to enable the user to retrieve
+the files manually.
 .SS "User Environment"
 Because the display environment in which
 .B mhshow
@@ -483,7 +441,6 @@ installation.
 ^Path:~^To determine the user's mail storage
 ^Current\-Folder:~^To find the default current folder
 ^Unseen\-Sequence:~^To name sequences denoting unseen messages
-^nmh-access-ftp:~^Program to retrieve contents via FTP
 ^mhshow-charset-<charset>~^Template for environment to render character sets
 ^mhshow-show-<type>*~^Template for displaying contents
 ^Pager:~^Default program to display text/plain content
index 15f4939..54495d7 100644 (file)
@@ -112,13 +112,7 @@ Note that regardless of the values given to the
 .B \-type
 switch,
 a multipart content (of any subtype listed above) is always acted
-upon.  Further note that if the
-.B \-type
-switch is used, and it is
-desirable to act on a message/external-body content, then the
-.B \-type
-switch must be used twice: once for message/external-body
-and once for the content externally referenced.
+upon.
 .SS "Storing the Contents"
 The
 .B mhstore
@@ -291,46 +285,10 @@ locate every partial necessary to reassemble the message, it will
 not store anything.
 .RE
 .SS "External Access"
-For contents of type message/external-body,
-\fImhstore\fR supports these access-types:
-.PP
-.IP \(bu 4
-afs
-.IP \(bu 4
-anon-ftp
-.IP \(bu 4
-ftp
-.IP \(bu 4
-local-file
-.IP \(bu 4
-mail-server
-.PP
-For the \*(lqanon-ftp\*(rq and \*(lqftp\*(rq access types,
-.B mhstore
-will look for the \*(lqnmh-access-ftp\*(rq
-profile entry, e.g.,
-.PP
-.RS 5
-nmh-access-ftp: myftp.sh
-.RE
-.PP
-to determine the pathname of a program to perform the FTP retrieval.
-This program is invoked with these arguments:
-.PP
-.RS 5
-.nf
-domain name of FTP-site
-username
-password
-remote directory
-remote filename
-local filename
-\*(lqascii\*(rq or \*(lqbinary\*(rq
-.fi
-.RE
-.PP
-The program should terminate with an exit status of zero if the
-retrieval is successful, and a non-zero exit status otherwise.
+.B Mhstore
+does not automatically retrieve message/external-body parts (anymore),
+but prints the relevant information to enable the user to retrieve
+the files manually.
 .SS "User Environment"
 Because the display environment in which
 .B mhstore
@@ -372,7 +330,6 @@ installation.
 .ta \w'ExtraBigProfileName  'u
 ^Path:~^To determine the user's mail storage
 ^Current\-Folder:~^To find the default current folder
-^nmh-access-ftp:~^Program to retrieve contents via FTP
 ^nmh-storage~^Directory to store contents
 ^mhstore-store-<type>*~^Template for storing contents
 .fi
index 1f1b79b..6c3d2c2 100644 (file)
@@ -61,7 +61,7 @@ SRCS = addrsbr.c ambigsw.c brkstring.c  \
        path.c pidwait.c pidstatus.c  \
        print_help.c print_sw.c print_version.c \
        putenv.c mhbasename.c  \
-       readconfig.c ruserpass.c seq_add.c seq_bits.c  \
+       readconfig.c seq_add.c seq_bits.c  \
        seq_del.c seq_getnum.c seq_list.c seq_nameok.c  \
        seq_print.c seq_read.c seq_save.c seq_setcur.c  \
        seq_setprev.c seq_setunseen.c signals.c  \
diff --git a/sbr/ruserpass.c b/sbr/ruserpass.c
deleted file mode 100644 (file)
index 0e169a5..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
-** Portions of this code are
-** Copyright (c) 1985 Regents of the University of California.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms are permitted
-** provided that the above copyright notice and this paragraph are
-** duplicated in all such forms and that any documentation,
-** advertising materials, and other materials related to such
-** distribution and use acknowledge that the software was developed
-** by the University of California, Berkeley.  The name of the
-** University may not be used to endorse or promote products derived
-** from this software without specific prior written permission.
-** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-*/
-
-#include <h/mh.h>
-#include <h/utils.h>
-#include <pwd.h>
-#include <errno.h>
-
-static FILE *cfile;
-
-#ifndef MAXHOSTNAMELEN
-# define MAXHOSTNAMELEN 64
-#endif
-
-#define DEFAULT 1
-#define LOGIN   2
-#define PASSWD  3
-#define ACCOUNT 4
-#define MACDEF  5
-#define ID     10
-#define MACH   11
-
-static char tokval[100];
-
-struct toktab {
-       char *tokstr;
-       int tval;
-};
-
-static struct toktab toktabs[] = {
-       { "default",  DEFAULT },
-       { "login",    LOGIN },
-       { "password", PASSWD },
-       { "passwd",   PASSWD },
-       { "account",  ACCOUNT },
-       { "machine",  MACH },
-       { "macdef",   MACDEF },
-       { 0,          0 }
-};
-
-/*
-** prototypes
-*/
-static int token(void);
-
-
-void
-ruserpass(char *host, char **aname, char **apass)
-{
-       char *hdir, buf[BUFSIZ];
-       int t, usedefault = 0;
-       struct stat stb;
-
-       hdir = getenv("HOME");
-       if (hdir == NULL)
-               hdir = ".";
-       snprintf(buf, sizeof(buf), "%s/.netrc", hdir);
-       cfile = fopen(buf, "r");
-       if (cfile == NULL) {
-               if (errno != ENOENT)
-                       perror(buf);
-               goto done;
-       }
-
-       while ((t = token())) {
-               switch(t) {
-               case DEFAULT:
-                       usedefault = 1;
-                       /* FALL THROUGH */
-
-               case MACH:
-                       if (!usedefault) {
-                               if (token() != ID)
-                                       continue;
-                               /*
-                                * Allow match either for user's host name.
-                                */
-                               if (mh_strcasecmp(host, tokval) == 0)
-                                       goto match;
-                               continue;
-                       }
-match:
-                       while ((t = token()) && t != MACH && t != DEFAULT) {
-                               switch(t) {
-                               case LOGIN:
-                                       if (token() && *aname == 0) {
-                                               *aname = mh_xmalloc((size_t) strlen(tokval) + 1);
-                                               strcpy(*aname, tokval);
-                                       }
-                                       break;
-                               case PASSWD:
-                                       if (fstat(fileno(cfile), &stb) >= 0 &&
-                                               (stb.st_mode & 077) != 0) {
-                                               /*
-                                               ** We make this a fatal
-                                               ** error to force the user
-                                               ** to correct it
-                                               */
-                                               advise(NULL, "Error - ~/.netrc file must not be world or group readable.");
-                                               adios(NULL, "Remove password or correct file permissions.");
-                                       }
-                                       if (token() && *apass == 0) {
-                                               *apass = mh_xmalloc((size_t) strlen(tokval) + 1);
-                                               strcpy(*apass, tokval);
-                                       }
-                                       break;
-                               case ACCOUNT:
-                                       break;
-
-                               case MACDEF:
-                                       goto done_close;
-                                       break;
-                               default:
-                                       fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
-                                       break;
-                               }
-                       }
-                       goto done;
-               }
-       }
-
-done_close:
-       fclose(cfile);
-
-done:
-       if (!*aname) {
-               char tmp[80];
-               char *myname;
-
-               if ((myname = getlogin()) == NULL) {
-                       struct passwd *pp;
-
-                       if ((pp = getpwuid(getuid())) != NULL)
-                               myname = pp->pw_name;
-               }
-               printf("Name (%s:%s): ", host, myname);
-
-               fgets(tmp, sizeof(tmp) - 1, stdin);
-               tmp[strlen(tmp) - 1] = '\0';
-               if (*tmp != '\0') {
-                       myname = tmp;
-               }
-
-               *aname = mh_xmalloc((size_t) strlen(myname) + 1);
-               strcpy(*aname, myname);
-       }
-
-       if (!*apass) {
-               char prompt[256];
-               char *mypass;
-
-               snprintf(prompt, sizeof(prompt), "Password (%s:%s): ", host, *aname);
-               mypass = nmh_getpass(prompt);
-
-               if (*mypass == '\0') {
-                       mypass = *aname;
-               }
-
-               *apass = mh_xmalloc((size_t) strlen(mypass) + 1);
-               strcpy(*apass, mypass);
-       }
-
-}
-
-static int
-token(void)
-{
-       char *cp;
-       int c;
-       struct toktab *t;
-
-       if (feof(cfile))
-               return (0);
-       while ((c = getc(cfile)) != EOF &&
-                  (c == '\n' || c == '\t' || c == ' ' || c == ','))
-               continue;
-       if (c == EOF)
-               return (0);
-       cp = tokval;
-       if (c == '"') {
-               while ((c = getc(cfile)) != EOF && c != '"') {
-                       if (c == '\\')
-                               c = getc(cfile);
-                       *cp++ = c;
-               }
-       } else {
-               *cp++ = c;
-               while ((c = getc(cfile)) != EOF
-                          && c != '\n' && c != '\t' && c != ' ' && c != ',') {
-                       if (c == '\\')
-                               c = getc(cfile);
-                       *cp++ = c;
-               }
-       }
-       *cp = 0;
-       if (tokval[0] == 0)
-               return (0);
-       for (t = toktabs; t->tokstr; t++)
-               if (strcmp(t->tokstr, tokval)==0)
-                       return (t->tval);
-       return (ID);
-}
index f659a30..d22e455 100644 (file)
@@ -86,9 +86,6 @@ static char prefix[] = "----- =_aaaaaaaaaa";
 int make_intermediates(char *);
 void content_error(char *, CT, char *, ...);
 
-/* ftpsbr.c */
-int ftp_get(char *, char *, char *, char *, char *, char *, int, int);
-
 /* mhfree.c */
 void free_content(CT);
 void free_ctinfo(CT);
index dd1277c..5fe5b2d 100644 (file)
@@ -30,7 +30,6 @@ void freects_done(int);
 static void free_text(CT);
 static void free_multi(CT);
 static void free_partial(CT);
-static void free_external(CT);
 
 
 /*
@@ -69,14 +68,8 @@ free_content(CT ct)
                break;
 
        case CT_MESSAGE:
-               switch (ct->c_subtype) {
-               case MESSAGE_PARTIAL:
+               if (ct->c_subtype == MESSAGE_PARTIAL) {
                        free_partial(ct);
-                       break;
-
-               case MESSAGE_EXTERNAL:
-                       free_external(ct);
-                       break;
                }
                break;
 
@@ -233,23 +226,6 @@ free_partial(CT ct)
 }
 
 
-static void
-free_external(CT ct)
-{
-       struct exbody *e;
-
-       if (!(e = (struct exbody *) ct->c_ctparams))
-               return;
-
-       free_content(e->eb_content);
-       if (e->eb_body)
-               free(e->eb_body);
-
-       free((char *) e);
-       ct->c_ctparams = NULL;
-}
-
-
 /*
 ** Free data structures related to encoding/decoding
 ** Content-Transfer-Encodings.
index 9cd331a..1777cf4 100644 (file)
@@ -36,7 +36,6 @@ static void list_single_message(CT, int, int, int);
 static int list_debug(CT);
 static int list_multi(CT, int, int, int, int);
 static int list_partial(CT, int, int, int, int);
-static int list_external(CT, int, int, int, int);
 static int list_encoding(CT);
 
 
@@ -106,22 +105,12 @@ list_switch(CT ct, int toplevel, int realsize, int verbose, int debug)
                break;
 
        case CT_MESSAGE:
-               switch (ct->c_subtype) {
-               case MESSAGE_PARTIAL:
+               if (ct->c_subtype == MESSAGE_PARTIAL) {
                        return list_partial(ct, toplevel, realsize, verbose,
                                                debug);
-                       break;
-
-               case MESSAGE_EXTERNAL:
-                       return list_external(ct, toplevel, realsize, verbose,
-                                               debug);
-                       break;
-
-               case MESSAGE_RFC822:
-               default:
+               } else {
                        return list_content(ct, toplevel, realsize, verbose,
                                                debug);
-                       break;
                }
                break;
 
@@ -205,7 +194,7 @@ list_content(CT ct, int toplevel, int realsize, int verbose, int debug)
                CI ci = &ct->c_ctinfo;
 
                for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
-                       printf("\t %s=\"%s\"\n", *ap, *ep);
+                       printf("\t\t%s=\"%s\"\n", *ap, *ep);
                }
 
                /*
@@ -346,54 +335,6 @@ list_partial(CT ct, int toplevel, int realsize, int verbose, int debug)
 
 
 /*
-** list content information for type "message/external"
-*/
-static int
-list_external(CT ct, int toplevel, int realsize, int verbose, int debug)
-{
-       struct exbody *e = (struct exbody *) ct->c_ctparams;
-
-       /*
-        * First list the information for the
-        * message/external content itself.
-        */
-       list_content(ct, toplevel, realsize, verbose, debug);
-
-       if (verbose) {
-               if (e->eb_name)
-                       printf("\t     name=\"%s\"\n", e->eb_name);
-               if (e->eb_dir)
-                       printf("\t     directory=\"%s\"\n", e->eb_dir);
-               if (e->eb_site)
-                       printf("\t     site=\"%s\"\n", e->eb_site);
-               if (e->eb_server)
-                       printf("\t     server=\"%s\"\n", e->eb_server);
-               if (e->eb_subject)
-                       printf("\t     subject=\"%s\"\n", e->eb_subject);
-
-               /* This must be defined */
-               printf("\t     access-type=\"%s\"\n", e->eb_access);
-
-               if (e->eb_mode)
-                       printf("\t     mode=\"%s\"\n", e->eb_mode);
-               if (e->eb_permission)
-                       printf("\t     permission=\"%s\"\n", e->eb_permission);
-
-               if (e->eb_flags == NOTOK)
-                       printf("\t     [service unavailable]\n");
-       }
-
-       /*
-       ** Now list the information for the external content
-       ** to which this content points.
-       */
-       list_content(e->eb_content, 0, realsize, verbose, debug);
-
-       return OK;
-}
-
-
-/*
 ** list information about the Content-Transfer-Encoding
 ** used by a content.
 */
index 01170a1..cf264c6 100644 (file)
@@ -105,13 +105,6 @@ static int openBase64(CT, char **);
 static int InitQuoted(CT);
 static int openQuoted(CT, char **);
 static int Init7Bit(CT);
-static int openExternal(CT, CT, CE, char **, int *);
-static int InitFile(CT);
-static int openFile(CT, char **);
-static int InitFTP(CT);
-static int openFTP(CT, char **);
-static int InitMail(CT);
-static int openMail(CT, char **);
 
 struct str2init str2cts[] = {
        { "application", CT_APPLICATION, InitApplication },
@@ -135,20 +128,6 @@ struct str2init str2ces[] = {
        { NULL,               CE_UNKNOWN,    NULL },
 };
 
-/*
-** NOTE WELL: si_key MUST NOT have value of NOTOK
-**
-** si_key is 1 if access method is anonymous.
-*/
-struct str2init str2methods[] = {
-       { "afs",         1, InitFile },
-       { "anon-ftp",    1, InitFTP },
-       { "ftp",         0, InitFTP },
-       { "local-file",  0, InitFile },
-       { "mail-server", 0, InitMail },
-       { NULL,          0, NULL }
-};
-
 
 int
 pidcheck(int status)
@@ -1353,15 +1332,9 @@ invalid_param:
 
        case MESSAGE_EXTERNAL:
                {
-               int exresult;
-               struct exbody *e;
                CT p;
                FILE *fp;
 
-               if ((e = (struct exbody *) calloc(1, sizeof(*e))) == NULL)
-                       adios(NULL, "out of memory");
-               ct->c_ctparams = (void *) e;
-
                if (!ct->c_fp && (ct->c_fp = fopen(ct->c_file, "r")) == NULL) {
                        advise(ct->c_file, "unable to open for reading");
                        return NOTOK;
@@ -1374,46 +1347,12 @@ invalid_param:
                        return NOTOK;
                }
 
-               e->eb_parent = ct;
-               e->eb_content = p;
-               p->c_ctexbody = e;
-               if ((exresult = params_external(ct, 0)) != NOTOK &&
-                               p->c_ceopenfnx == openMail) {
-                       int cc, size;
-                       char *bp;
-
-                       if ((size = ct->c_end - p->c_begin) <= 0) {
-                               if (!e->eb_subject)
-                                       content_error(NULL, ct, "empty body for access-type=mail-server");
-                               goto no_body;
-                       }
-
-                       e->eb_body = bp = mh_xmalloc((unsigned) size);
-                       fseek(p->c_fp, p->c_begin, SEEK_SET);
-                       while (size > 0)
-                               switch (cc = fread(bp, sizeof(*bp), size, p->c_fp)) {
-                               case NOTOK:
-                                       adios("failed", "fread");
-                               case OK:
-                                       adios(NULL, "unexpected EOF from fread");
-                               default:
-                                       bp += cc, size -= cc;
-                                       break;
-                               }
-                       *bp = 0;
-               }
-no_body:
                p->c_fp = NULL;
                p->c_end = p->c_begin;
 
                fclose(ct->c_fp);
                ct->c_fp = NULL;
 
-               if (exresult == NOTOK)
-                       return NOTOK;
-               if (e->eb_flags == NOTOK)
-                       return OK;
-
                switch (p->c_type) {
                case CT_MULTIPART:
                        break;
@@ -1421,9 +1360,8 @@ no_body:
                case CT_MESSAGE:
                        if (p->c_subtype != MESSAGE_RFC822)
                                break;
-                               /* else fall... */
+                       /* else fall... */
                default:
-                       e->eb_partno = ct->c_partno;
                        if (p->c_ctinitfnx)
                                (*p->c_ctinitfnx) (p);
                        break;
@@ -1439,83 +1377,6 @@ no_body:
 }
 
 
-int
-params_external(CT ct, int composing)
-{
-       char **ap, **ep;
-       struct exbody *e = (struct exbody *) ct->c_ctparams;
-       CI ci = &ct->c_ctinfo;
-
-       for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
-               if (!mh_strcasecmp(*ap, "access-type")) {
-                       struct str2init *s2i;
-                       CT p = e->eb_content;
-
-                       for (s2i = str2methods; s2i->si_key; s2i++)
-                               if (!mh_strcasecmp(*ep, s2i->si_key))
-                                       break;
-                       if (!s2i->si_key) {
-                               e->eb_access = *ep;
-                               e->eb_flags = NOTOK;
-                               p->c_encoding = CE_EXTERNAL;
-                               continue;
-                       }
-                       e->eb_access = s2i->si_key;
-                       e->eb_flags = s2i->si_val;
-                       p->c_encoding = CE_EXTERNAL;
-
-                       /* Call the Init function for this external type */
-                       if ((*s2i->si_init)(p) == NOTOK)
-                               return NOTOK;
-                       continue;
-               }
-               if (!mh_strcasecmp(*ap, "name")) {
-                       e->eb_name = *ep;
-                       continue;
-               }
-               if (!mh_strcasecmp(*ap, "permission")) {
-                       e->eb_permission = *ep;
-                       continue;
-               }
-               if (!mh_strcasecmp(*ap, "site")) {
-                       e->eb_site = *ep;
-                       continue;
-               }
-               if (!mh_strcasecmp(*ap, "directory")) {
-                       e->eb_dir = *ep;
-                       continue;
-               }
-               if (!mh_strcasecmp(*ap, "mode")) {
-                       e->eb_mode = *ep;
-                       continue;
-               }
-               if (!mh_strcasecmp(*ap, "size")) {
-                       sscanf(*ep, "%lu", &e->eb_size);
-                       continue;
-               }
-               if (!mh_strcasecmp(*ap, "server")) {
-                       e->eb_server = *ep;
-                       continue;
-               }
-               if (!mh_strcasecmp(*ap, "subject")) {
-                       e->eb_subject = *ep;
-                       continue;
-               }
-               if (composing && !mh_strcasecmp(*ap, "body")) {
-                       e->eb_body = getcpy(*ep);
-                       continue;
-               }
-       }
-
-       if (!e->eb_access) {
-               advise(NULL, "invalid parameters for \"%s/%s\" type in message %s's %s field", ci->ci_type, ci->ci_subtype, ct->c_file, TYPE_FIELD);
-               return NOTOK;
-       }
-
-       return OK;
-}
-
-
 /*
 ** APPLICATION
 */
@@ -2254,359 +2115,3 @@ clean_up:
        }
        return NOTOK;
 }
-
-
-/*
-** External
-*/
-
-static int
-openExternal(CT ct, CT cb, CE ce, char **file, int *fd)
-{
-       if (ce->ce_fp) {
-               fseek(ce->ce_fp, 0L, SEEK_SET);
-               goto ready_already;
-       }
-
-       if (ce->ce_file) {
-               if ((ce->ce_fp = fopen(ce->ce_file, "r")) == NULL) {
-                       content_error(ce->ce_file, ct,
-                                       "unable to fopen for reading");
-                       return NOTOK;
-               }
-               goto ready_already;
-       }
-
-       return OK;
-
-ready_already:
-       *file = ce->ce_file;
-       *fd = fileno(ce->ce_fp);
-       return DONE;
-}
-
-/*
-** File
-*/
-
-static int
-InitFile(CT ct)
-{
-       return init_encoding(ct, openFile);
-}
-
-
-static int
-openFile(CT ct, char **file)
-{
-       int fd;
-       struct exbody *e = ct->c_ctexbody;
-       CE ce = ct->c_cefile;
-
-       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_name) {
-               content_error(NULL, ct, "missing name parameter");
-               return NOTOK;
-       }
-
-       ce->ce_file = getcpy(e->eb_name);
-       ce->ce_unlink = 0;
-
-       if ((ce->ce_fp = fopen(ce->ce_file, "r")) == NULL) {
-               content_error(ce->ce_file, ct, "unable to fopen for reading");
-               return NOTOK;
-       }
-
-       fseek(ce->ce_fp, 0L, SEEK_SET);
-       *file = ce->ce_file;
-       return fileno(ce->ce_fp);
-}
-
-/*
-** FTP
-*/
-
-static int
-InitFTP(CT ct)
-{
-       return init_encoding(ct, openFTP);
-}
-
-
-static int
-openFTP(CT ct, char **file)
-{
-       int fd;
-       int len, buflen;
-       char *bp, *ftp, *user, *pass;
-       char buffer[BUFSIZ];
-       struct exbody *e;
-       CE ce;
-       static char *username = NULL;
-       static char *password = NULL;
-       int child_id, vecp;
-       char *vec[9];
-
-       e  = ct->c_ctexbody;
-       ce = ct->c_cefile;
-
-       if ((ftp = context_find(nmhaccessftp)) && !*ftp)
-               ftp = NULL;
-
-       if (!ftp)
-               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_name || !e->eb_site) {
-               content_error(NULL, ct, "missing %s parameter",
-                               e->eb_name ? "site": "name");
-               return NOTOK;
-       }
-
-       if (xpid) {
-               if (xpid < 0)
-                       xpid = -xpid;
-               pidcheck(pidwait(xpid, NOTOK));
-               xpid = 0;
-       }
-
-       /* Get the buffer ready to go */
-       bp = buffer;
-       buflen = sizeof(buffer);
-
-       /*
-       ** Construct the query message for user
-       */
-       snprintf(bp, buflen, "Retrieve %s", e->eb_name);
-       len = strlen(bp);
-       bp += len;
-       buflen -= len;
-
-       if (e->eb_partno) {
-               snprintf(bp, buflen, " (content %s)", e->eb_partno);
-               len = strlen(bp);
-               bp += len;
-               buflen -= len;
-       }
-
-       snprintf(bp, buflen, "\n    using %sFTP from site %s",
-                       e->eb_flags ? "anonymous " : "", e->eb_site);
-       len = strlen(bp);
-       bp += len;
-       buflen -= len;
-
-       if (e->eb_size > 0) {
-               snprintf(bp, buflen, " (%lu octets)", e->eb_size);
-               len = strlen(bp);
-               bp += len;
-               buflen -= len;
-       }
-       snprintf(bp, buflen, "? ");
-
-       /*
-       ** Now, check the answer
-       */
-       if (!getanswer(buffer))
-               return NOTOK;
-
-       if (e->eb_flags) {
-               user = "anonymous";
-               snprintf(buffer, sizeof(buffer), "%s@%s", getusername(),
-                               LocalName());
-               pass = buffer;
-       } else {
-               ruserpass(e->eb_site, &username, &password);
-               user = username;
-               pass = password;
-       }
-
-       ce->ce_unlink = (*file == NULL);
-
-       if (*file)
-               ce->ce_file = getcpy(*file);
-       else
-               ce->ce_file = getcpy(m_mktemp(tmp, NULL, NULL));
-
-       if ((ce->ce_fp = fopen(ce->ce_file, "w+")) == NULL) {
-               content_error (ce->ce_file, ct,
-                               "unable to fopen for reading/writing");
-               return NOTOK;
-       }
-
-       vecp = 0;
-       vec[vecp++] = mhbasename(ftp);
-       vec[vecp++] = e->eb_site;
-       vec[vecp++] = user;
-       vec[vecp++] = pass;
-       vec[vecp++] = e->eb_dir;
-       vec[vecp++] = e->eb_name;
-       vec[vecp++] = ce->ce_file,
-       vec[vecp++] = e->eb_mode &&
-                       !mh_strcasecmp(e->eb_mode, "ascii") ?
-                       "ascii" : "binary";
-       vec[vecp] = NULL;
-
-       fflush(stdout);
-
-       switch (child_id = fork()) {
-       case NOTOK:
-               adios("fork", "unable to");
-               /* NOTREACHED */
-
-       case OK:
-               close(fileno(ce->ce_fp));
-               execvp(ftp, vec);
-               fprintf(stderr, "unable to exec ");
-               perror(ftp);
-               _exit(-1);
-               /* NOTREACHED */
-
-       default:
-               if (pidXwait(child_id, NULL)) {
-                       username = password = NULL;
-                       ce->ce_unlink = 1;
-                       return NOTOK;
-               }
-               break;
-       }
-
-       fseek(ce->ce_fp, 0L, SEEK_SET);
-       *file = ce->ce_file;
-       return fileno(ce->ce_fp);
-}
-
-
-/*
-** Mail
-*/
-
-static int
-InitMail(CT ct)
-{
-       return init_encoding(ct, openMail);
-}
-
-
-static int
-openMail(CT ct, char **file)
-{
-       int child_id, fd, vecp;
-       int len, buflen;
-       char *bp, buffer[BUFSIZ], *vec[7];
-       struct exbody *e = ct->c_ctexbody;
-       CE ce = ct->c_cefile;
-
-       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_server) {
-               content_error(NULL, ct, "missing server parameter");
-               return NOTOK;
-       }
-
-       if (xpid) {
-               if (xpid < 0)
-                       xpid = -xpid;
-               pidcheck(pidwait(xpid, NOTOK));
-               xpid = 0;
-       }
-
-       /* Get buffer ready to go */
-       bp = buffer;
-       buflen = sizeof(buffer);
-
-       /* Now, construct query message */
-       snprintf(bp, buflen, "Retrieve content");
-       len = strlen(bp);
-       bp += len;
-       buflen -= len;
-
-       if (e->eb_partno) {
-               snprintf(bp, buflen, " %s", e->eb_partno);
-               len = strlen(bp);
-               bp += len;
-               buflen -= len;
-       }
-
-       snprintf(bp, buflen, " by asking %s\n\n%s\n? ", e->eb_server,
-                       e->eb_subject ? e->eb_subject : e->eb_body);
-
-       /* Now, check answer */
-       if (!getanswer(buffer))
-               return NOTOK;
-
-       vecp = 0;
-       vec[vecp++] = "mhmail";
-       vec[vecp++] = e->eb_server;
-       vec[vecp++] = "-subject";
-       vec[vecp++] = e->eb_subject ? e->eb_subject : "mail-server request";
-       vec[vecp++] = "-body";
-       vec[vecp++] = e->eb_body;
-       vec[vecp] = NULL;
-
-       switch (child_id = fork()) {
-       case NOTOK:
-               advise("fork", "unable to");
-               return NOTOK;
-
-       case OK:
-               execvp(*vec, vec);
-               fprintf(stderr, "unable to exec ");
-               perror(*vec);
-               _exit(-1);
-               /* NOTREACHED */
-
-       default:
-               if (pidXwait(child_id, NULL) == OK)
-                       advise(NULL, "request sent");
-               break;
-       }
-
-       if (*file == NULL) {
-               ce->ce_file = getcpy(m_mktemp(tmp, NULL, NULL));
-               ce->ce_unlink = 1;
-       } else {
-               ce->ce_file = getcpy(*file);
-               ce->ce_unlink = 0;
-       }
-
-       if ((ce->ce_fp = fopen(ce->ce_file, "w+")) == NULL) {
-               content_error(ce->ce_file, ct,
-                               "unable to fopen for reading/writing");
-               return NOTOK;
-       }
-
-       /*
-       ** showproc is for mhshow and mhstore, though mhlist -debug
-       ** prints it, too.
-       */
-       if (ct->c_showproc)
-               free(ct->c_showproc);
-       ct->c_showproc = getcpy("true");
-
-       fseek(ce->ce_fp, 0L, SEEK_SET);
-       *file = ce->ce_file;
-       return fileno(ce->ce_fp);
-}
index 2b69c19..adb0da7 100644 (file)
@@ -963,24 +963,34 @@ show_partial(CT ct, int alternate)
 
 
 /*
-** Show content of type "message/external".
-**
-** THE ERROR CHECKING IN THIS ONE IS NOT DONE YET.
+** Show how to retrieve content of type "message/external".
 */
-
 static int
 show_external(CT ct, int alternate)
 {
-       struct exbody *e = (struct exbody *) ct->c_ctparams;
-       CT p = e->eb_content;
-
-       if (!type_ok(p, 0))
-               return OK;
-
-       return show_switch(p, alternate);
-
-#if 0
-       content_error(NULL, p, "don't know how to display content");
-       return NOTOK;
-#endif
+       char **ap, **ep;
+       char *msg;
+       FILE *fp;
+       char buf[BUFSIZ];
+
+       msg = add("You need to fetch the contents yourself:", NULL);
+       ap = ct->c_ctinfo.ci_attrs;
+       ep = ct->c_ctinfo.ci_values;
+       for (; *ap; ap++, ep++) {
+               msg = add(concat("\n\t", *ap, ": ", *ep, NULL), msg);
+       }
+       if (!(fp = fopen(ct->c_file, "r"))) {
+               adios(ct->c_file, "unable to open");
+       }
+       fseek(fp, ct->c_begin, SEEK_SET);
+       while (!feof(fp) && ftell(fp) < ct->c_end) {
+               if (!fgets(buf, sizeof buf, fp)) {
+                       adios(ct->c_file, "unable to read");
+               }
+               *strchr(buf, '\n') = '\0';
+               msg = add(concat("\n\t", buf, NULL), msg);
+       }
+       fclose(fp);
+       content_error(NULL, ct, msg);
+       return OK;
 }
index 50c911c..f4d664d 100644 (file)
@@ -466,7 +466,6 @@ store_switch(CT ct)
 ** Generic routine to store a MIME content.
 ** (application, audio, video, image, text, message/rfc922)
 */
-
 static int
 store_generic(CT ct)
 {
@@ -477,10 +476,8 @@ store_generic(CT ct)
        ** Check if the content specifies a filename in its MIME parameters.
        ** Don't bother with this for type "message"
        ** (only the "message" subtype "rfc822" will use store_generic).
-       ** The storeproc may already be defined, if this content
-       ** is part of a "message/external", for instance.
        */
-       if (autosw && ct->c_type != CT_MESSAGE && !ct->c_storeproc) {
+       if (autosw && ct->c_type != CT_MESSAGE) {
                /*
                ** Check the attribute/value pairs, for the attribute "name".
                ** If found, take the basename, do a few sanity checks and
@@ -633,50 +630,36 @@ losing:
 
 
 /*
-** Store content from a message of type "message/external".
+** Show how to retrieve content of type "message/external".
 */
-
 static int
 store_external(CT ct)
 {
-       int result = NOTOK;
-       struct exbody *e = (struct exbody *) ct->c_ctparams;
-       CT p = e->eb_content;
-
-       if (!type_ok(p, 1))
-               return OK;
+       char **ap, **ep;
+       char *msg;
+       FILE *fp;
+       char buf[BUFSIZ];
 
-       /*
-       ** Check if the parameters for the external body
-       ** specified a filename.
-       */
-       if (autosw) {
-               char *cp;
-
-               cp = mhbasename(e->eb_name);
-               if (*cp && *cp!='.' && *cp!='|' && *cp!='!' &&
-                               !strchr(cp, '%')) {
-                       /* filename looks good: use it */
-                       if (!ct->c_storeproc)
-                               ct->c_storeproc = getcpy(cp);
-                       if (!p->c_storeproc)
-                               p->c_storeproc = getcpy(cp);
+       msg = add("You need to fetch the contents yourself:", NULL);
+       ap = ct->c_ctinfo.ci_attrs;
+       ep = ct->c_ctinfo.ci_values;
+       for (; *ap; ap++, ep++) {
+               msg = add(concat("\n\t", *ap, ": ", *ep, NULL), msg);
+       }
+       if (!(fp = fopen(ct->c_file, "r"))) {
+               adios(ct->c_file, "unable to open");
+       }
+       fseek(fp, ct->c_begin, SEEK_SET);
+       while (!feof(fp) && ftell(fp) < ct->c_end) {
+               if (!fgets(buf, sizeof buf, fp)) {
+                       adios(ct->c_file, "unable to read");
                }
+               *strchr(buf, '\n') = '\0';
+               msg = add(concat("\n\t", buf, NULL), msg);
        }
-
-       /*
-       ** Since we will let the Content structure for the
-       ** external body substitute for the current content,
-       ** we temporarily change its partno (number inside
-       ** multipart), so everything looks right.
-       */
-       p->c_partno = ct->c_partno;
-
-       /* we probably need to check if content is really there */
-       result = store_switch(p);
-
-       p->c_partno = NULL;
-       return result;
+       fclose(fp);
+       advise(NULL, msg);
+       return OK;
 }
 
 
@@ -766,7 +749,7 @@ store_content(CT ct, CT p)
        ** 4) Else if content is "message", use "+" (current folder)
        ** 5) Else use string "%m%P.%s".
        */
-       if ((cp = ct->c_storeproc) == NULL || *cp == '\0') {
+       if (!(cp = ct->c_storeproc) || !*cp) {
                CI ci = &ct->c_ctinfo;
 
                snprintf(buffer, sizeof(buffer), "%s-store-%s/%s",