extern pid_t xpid; /* mhshowsbr.c */
-/* cache policies */
-extern int rcachesw; /* mhcachesbr.c */
-extern int wcachesw; /* mhcachesbr.c */
-
/*
** Directory to place temp files. This must
** be set before these routines are called.
};
-/* mhcachesbr.c */
-int find_cache(CT, int, int *, char *, char *, int);
-
/* mhmisc.c */
int part_ok(CT, int);
int type_ok(CT, int);
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)
static int
InitText(CT ct)
{
- char buffer[BUFSIZ];
- char *chset = NULL;
- char **ap, **ep, *cp;
+ char **ap, **ep;
struct k2v *kv;
struct text *t;
CI ci = &ct->c_ctinfo;
/* check if content specified a character set */
if (*ap) {
+ /* store its name */
+ ct->c_charset = getcpy(norm_charmap(*ep));
/* match character set or set to CHARSET_UNKNOWN */
for (kv = Charset; kv->kv_key; kv++) {
if (!mh_strcasecmp(*ep, kv->kv_key)) {
- chset = *ep;
break;
}
}
t->tx_charset = CHARSET_UNSPECIFIED;
}
- /*
- ** If we can not handle character set natively,
- ** then check profile for string to modify the
- ** terminal or display method.
- **
- ** termproc is for mhshow, though mhlist -debug prints it, too.
- */
- if (chset != NULL && !check_charset(chset, strlen(chset))) {
- snprintf(buffer, sizeof(buffer), "%s-charset-%s",
- invo_name, chset);
- if ((cp = context_find(buffer)))
- ct->c_termproc = getcpy(cp);
- }
-
return OK;
}
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
*/
cp = context_find(buffer);
if (cp == NULL || *cp == '\0') {
snprintf(buffer, sizeof(buffer), "%s-suffix-%s", invo_name,
- ci->ci_type);
+ ci->ci_type);
cp = context_find(buffer);
}
if (cp != NULL && *cp != '\0') {
int cc, len, quoted, own_ct_fp = 0;
unsigned char *cp, *ep;
char buffer[BUFSIZ];
- unsigned char mask;
+ unsigned char mask = 0;
CE ce;
/* sbeck -- handle suffixes */
CI ci;
}
if (cp != NULL && *cp != '\0') {
if (ce->ce_unlink) {
- // Temporary file already exists, so we rename to
- // version with extension.
+ /*
+ ** Temporary file already exists, so we rename to
+ ** version with extension.
+ */
char *file_org = strdup(ce->ce_file);
ce->ce_file = add(cp, ce->ce_file);
if (rename(file_org, ce->ce_file)) {
}
quoted = 0;
-#ifdef lint
- mask = 0;
-#endif
fseek(ct->c_fp, ct->c_begin, SEEK_SET);
while (len > 0) {
cp = context_find(buffer);
if (cp == NULL || *cp == '\0') {
snprintf(buffer, sizeof(buffer), "%s-suffix-%s", invo_name,
- ci->ci_type);
+ ci->ci_type);
cp = context_find(buffer);
}
if (cp != NULL && *cp != '\0') {
}
return NOTOK;
}
-
-
-/*
-** External
-*/
-
-static int
-openExternal(CT ct, CT cb, CE ce, char **file, int *fd)
-{
- char cachefile[BUFSIZ];
-
- 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;
- }
-
- if (find_cache(ct, rcachesw, (int *) 0, cb->c_id,
- cachefile, sizeof(cachefile)) != NOTOK) {
- if ((ce->ce_fp = fopen(cachefile, "r"))) {
- ce->ce_file = getcpy(cachefile);
- ce->ce_unlink = 0;
- goto ready_already;
- } else {
- admonish(cachefile, "unable to fopen for reading");
- }
- }
-
- 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, cachetype;
- char cachefile[BUFSIZ];
- 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;
- }
-
- if ((!e->eb_permission ||
- mh_strcasecmp(e->eb_permission, "read-write")) &&
- find_cache(NULL, wcachesw, &cachetype,
- e->eb_content->c_id, cachefile, sizeof(cachefile))
- != NOTOK) {
- int mask;
- FILE *fp;
-
- mask = umask(cachetype ? ~m_gmprot() : 0222);
- if ((fp = fopen(cachefile, "w"))) {
- int cc;
- char buffer[BUFSIZ];
- FILE *gp = ce->ce_fp;
-
- fseek(gp, 0L, SEEK_SET);
-
- while ((cc = fread(buffer, sizeof(*buffer),
- sizeof(buffer), gp)) > 0)
- fwrite(buffer, sizeof(*buffer), cc, fp);
- fflush(fp);
-
- if (ferror(gp)) {
- admonish(ce->ce_file, "error reading");
- unlink(cachefile);
- } else if (ferror(fp)) {
- admonish(cachefile, "error writing");
- unlink(cachefile);
- }
- fclose(fp);
- }
- umask(mask);
- }
-
- 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 cachetype, caching, fd;
- int len, buflen;
- char *bp, *ftp, *user, *pass;
- char buffer[BUFSIZ], cachefile[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);
- caching = 0;
- cachefile[0] = '\0';
- if ((!e->eb_permission ||
- mh_strcasecmp(e->eb_permission, "read-write")) &&
- find_cache(NULL, wcachesw, &cachetype,
- e->eb_content->c_id, cachefile, sizeof(cachefile))
- != NOTOK) {
- if (*file == NULL) {
- ce->ce_unlink = 0;
- caching = 1;
- }
- }
-
- if (*file)
- ce->ce_file = getcpy(*file);
- else if (caching)
- ce->ce_file = getcpy(cachefile);
- 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;
- }
-
- if (cachefile[0]) {
- if (caching)
- chmod(cachefile, cachetype ? m_gmprot() : 0444);
- else {
- int mask;
- FILE *fp;
-
- mask = umask(cachetype ? ~m_gmprot() : 0222);
- if ((fp = fopen(cachefile, "w"))) {
- int cc;
- FILE *gp = ce->ce_fp;
-
- fseek(gp, 0L, SEEK_SET);
-
- while ((cc= fread(buffer, sizeof(*buffer),
- sizeof(buffer), gp)) > 0)
- fwrite(buffer, sizeof(*buffer), cc, fp);
- fflush(fp);
-
- if (ferror(gp)) {
- admonish(ce->ce_file, "error reading");
- unlink(cachefile);
- } else if (ferror(fp)) {
- admonish(cachefile, "error writing");
- unlink(cachefile);
- }
- fclose(fp);
- }
- umask(mask);
- }
- }
-
- 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);
-}