/* 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";
extern char *mimetypequery;
extern char *mimetypequeryproc;
extern char *msgprot;
-extern char *nmhaccessftp;
extern char *nmhstorage;
extern char *nsequence;
extern char *profile;
/* 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 */
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
*/
};
extern struct str2init str2cts[];
extern struct str2init str2ces[];
-extern struct str2init str2methods[];
/*
** prototypes
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);
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 *);
.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 ^ ~
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
.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
^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
.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
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
.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
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 \
+++ /dev/null
-/*
-** 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);
-}
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);
static void free_text(CT);
static void free_multi(CT);
static void free_partial(CT);
-static void free_external(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;
}
-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.
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);
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;
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);
}
/*
/*
-** 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.
*/
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 },
{ 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)
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;
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;
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;
}
-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
*/
}
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);
-}
/*
-** 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;
}
** Generic routine to store a MIME content.
** (application, audio, video, image, text, message/rfc922)
*/
-
static int
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
/*
-** 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;
}
** 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",