From: markus schnalke Date: Thu, 12 Apr 2012 21:05:47 +0000 (+0200) Subject: mhshow/mhstore: Removed support for retrieving message/external-body parts. X-Git-Tag: mmh-thesis-end~91 X-Git-Url: http://git.marmaro.de/?p=mmh;a=commitdiff_plain;h=55e1d8c654ee0f7c45b9361ce34617983b454c32 mhshow/mhstore: Removed support for retrieving message/external-body parts. 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.) --- diff --git a/config/config.c b/config/config.c index 70a9a40..1caea47 100644 --- a/config/config.c +++ b/config/config.c @@ -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 --- 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; diff --git a/h/mhparse.h b/h/mhparse.h index af9b8ca..2d88127 100644 --- a/h/mhparse.h +++ b/h/mhparse.h @@ -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); diff --git a/h/prototypes.h b/h/prototypes.h index ba33a03..f2c4652 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -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 *); diff --git a/man/mhlist.man1 b/man/mhlist.man1 index b9b098c..f42498b 100644 --- a/man/mhlist.man1 +++ b/man/mhlist.man1 @@ -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 ^ ~ diff --git a/man/mhshow.man1 b/man/mhshow.man1 index 8ebc7ba..9b6465d 100644 --- a/man/mhshow.man1 +++ b/man/mhshow.man1 @@ -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-~^Template for environment to render character sets ^mhshow-show-*~^Template for displaying contents ^Pager:~^Default program to display text/plain content diff --git a/man/mhstore.man1 b/man/mhstore.man1 index 15f4939..54495d7 100644 --- a/man/mhstore.man1 +++ b/man/mhstore.man1 @@ -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-*~^Template for storing contents .fi diff --git a/sbr/Makefile.in b/sbr/Makefile.in index 1f1b79b..6c3d2c2 100644 --- a/sbr/Makefile.in +++ b/sbr/Makefile.in @@ -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 index 0e169a5..0000000 --- a/sbr/ruserpass.c +++ /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 -#include -#include -#include - -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); -} diff --git a/uip/mhbuild.c b/uip/mhbuild.c index f659a30..d22e455 100644 --- a/uip/mhbuild.c +++ b/uip/mhbuild.c @@ -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); diff --git a/uip/mhfree.c b/uip/mhfree.c index dd1277c..5fe5b2d 100644 --- a/uip/mhfree.c +++ b/uip/mhfree.c @@ -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. diff --git a/uip/mhlistsbr.c b/uip/mhlistsbr.c index 9cd331a..1777cf4 100644 --- a/uip/mhlistsbr.c +++ b/uip/mhlistsbr.c @@ -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. */ diff --git a/uip/mhparse.c b/uip/mhparse.c index 01170a1..cf264c6 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -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); -} diff --git a/uip/mhshowsbr.c b/uip/mhshowsbr.c index 2b69c19..adb0da7 100644 --- a/uip/mhshowsbr.c +++ b/uip/mhshowsbr.c @@ -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; } diff --git a/uip/mhstore.c b/uip/mhstore.c index 50c911c..f4d664d 100644 --- a/uip/mhstore.c +++ b/uip/mhstore.c @@ -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",