/*
+ * Copyright notice from original mutt:
* Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- */
+ *
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
/*
* rfc1524 defines a format for the Multimedia Mail Configuration, which
* rfc1524.
*/
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <lib-lib/mem.h>
+#include <lib-lib/str.h>
+#include <lib-lib/ascii.h>
+#include <lib-lib/macros.h>
+#include <lib-lib/file.h>
+
#include "mutt.h"
#include "rfc1524.h"
+#include "attach.h"
+
+#include "lib/debug.h"
#include <string.h>
#include <stdlib.h>
* In addition, this function returns a 0 if the command works on a file,
* and 1 if the command works on a pipe.
*/
-int rfc1524_expand_command (BODY *a, char *filename, char *_type,
- char *command, int clen)
+int rfc1524_expand_command (BODY * a, char *filename, char *_type,
+ char *command, int clen)
{
- int x=0,y=0;
+ int x = 0, y = 0;
int needspipe = TRUE;
char buf[LONG_STRING];
char type[LONG_STRING];
-
- strfcpy (type, _type, sizeof (type));
-
+
+ m_strcpy(type, sizeof(type), _type);
+
if (option (OPTMAILCAPSANITIZE))
mutt_sanitize_filename (type, 0);
- while (command[x] && x<clen && y<sizeof(buf))
- {
+ while (command[x] && x < clen && y < sizeof (buf)) {
if (command[x] == '\\') {
x++;
buf[y++] = command[x++];
}
- else if (command[x] == '%')
- {
+ else if (command[x] == '%') {
x++;
- if (command[x] == '{')
- {
- char param[STRING];
- char pvalue[STRING];
- char *_pvalue;
- int z = 0;
-
- x++;
- while (command[x] && command[x] != '}' && z<sizeof(param))
- param[z++] = command[x++];
- param[z] = '\0';
-
- _pvalue = mutt_get_parameter (param, a->parameter);
- strfcpy (pvalue, NONULL(_pvalue), sizeof (pvalue));
- if (option (OPTMAILCAPSANITIZE))
- mutt_sanitize_filename (pvalue, 0);
-
- y += mutt_quote_filename (buf + y, sizeof (buf) - y, pvalue);
+ if (command[x] == '{') {
+ char param[STRING];
+ char pvalue[STRING];
+ char *_pvalue;
+ int z = 0;
+
+ x++;
+ while (command[x] && command[x] != '}' && z < sizeof (param))
+ param[z++] = command[x++];
+ param[z] = '\0';
+
+ _pvalue = mutt_get_parameter (param, a->parameter);
+ m_strcpy(pvalue, sizeof(pvalue), NONULL(_pvalue));
+ if (option (OPTMAILCAPSANITIZE))
+ mutt_sanitize_filename (pvalue, 0);
+
+ y += mutt_quote_filename (buf + y, sizeof (buf) - y, pvalue);
}
- else if (command[x] == 's' && filename != NULL)
- {
- y += mutt_quote_filename (buf + y, sizeof (buf) - y, filename);
- needspipe = FALSE;
+ else if (command[x] == 's' && filename != NULL) {
+ y += mutt_quote_filename (buf + y, sizeof (buf) - y, filename);
+ needspipe = FALSE;
}
- else if (command[x] == 't')
- {
- y += mutt_quote_filename (buf + y, sizeof (buf) - y, type);
+ else if (command[x] == 't') {
+ y += mutt_quote_filename (buf + y, sizeof (buf) - y, type);
}
x++;
}
buf[y++] = command[x++];
}
buf[y] = '\0';
- strfcpy (command, buf, clen);
+ m_strcpy(command, clen, buf);
return needspipe;
}
if (!s)
return NULL;
- while ((ch = strpbrk (s, ";\\")) != NULL)
- {
- if (*ch == '\\')
- {
+ while ((ch = strpbrk (s, ";\\")) != NULL) {
+ if (*ch == '\\') {
s = ch + 1;
if (*s)
- s++;
+ s++;
}
- else
- {
- *ch++ = 0;
- SKIPWS (ch);
+ else {
+ *ch++ = '\0';
+ ch = vskipspaces(ch);
break;
}
}
- mutt_remove_trailing_ws (s);
+ m_strrtrim(s);
return ch;
}
static int get_field_text (char *field, char **entry,
- char *type, char *filename, int line)
+ char *type, char *filename, int line)
{
- field = mutt_skip_whitespace (field);
- if (*field == '=')
- {
- if (entry)
- {
- field++;
- field = mutt_skip_whitespace (field);
- mutt_str_replace (entry, field);
+ field = vskipspaces(field);
+ if (*field == '=') {
+ if (entry) {
+ field = vskipspaces(field + 1);
+ m_strreplace(entry, field);
}
return 1;
}
- else
- {
+ else {
mutt_error (_("Improperly formated entry for type %s in \"%s\" line %d"),
- type, filename, line);
+ type, filename, line);
return 0;
}
}
-static int rfc1524_mailcap_parse (BODY *a,
- char *filename,
- char *type,
- rfc1524_entry *entry,
- int opt)
+static int rfc1524_mailcap_parse (BODY * a,
+ char *filename,
+ char *type, rfc1524_entry * entry, int opt)
{
FILE *fp;
char *buf = NULL;
return FALSE;
btlen = ch - type;
- if ((fp = fopen (filename, "r")) != NULL)
- {
- while (!found && (buf = mutt_read_line (buf, &buflen, fp, &line)) != NULL)
- {
+ if ((fp = fopen (filename, "r")) != NULL) {
+ while (!found && (buf = mutt_read_line (buf, &buflen, fp, &line)) != NULL) {
/* ignore comments */
if (*buf == '#')
- continue;
- dprint (2, (debugfile, "mailcap entry: %s\n", buf));
+ continue;
+ debug_print (2, ("mailcap entry: %s\n", buf));
/* check type */
ch = get_field (buf);
- if (ascii_strcasecmp (buf, type) &&
- (ascii_strncasecmp (buf, type, btlen) ||
- (buf[btlen] != 0 && /* implicit wild */
- mutt_strcmp (buf + btlen, "/*")))) /* wildsubtype */
- continue;
+ if (ascii_strcasecmp (buf, type) && (ascii_strncasecmp (buf, type, btlen) || (buf[btlen] != 0 && /* implicit wild */
+ m_strcmp(buf + btlen, "/*")))) /* wildsubtype */
+ continue;
/* next field is the viewcommand */
field = ch;
ch = get_field (ch);
if (entry)
- entry->command = safe_strdup (field);
+ entry->command = m_strdup(field);
/* parse the optional fields */
found = TRUE;
editcommand = FALSE;
printcommand = FALSE;
- while (ch)
- {
- field = ch;
- ch = get_field (ch);
- dprint (2, (debugfile, "field: %s\n", field));
-
- if (!ascii_strcasecmp (field, "needsterminal"))
- {
- if (entry)
- entry->needsterminal = TRUE;
- }
- else if (!ascii_strcasecmp (field, "copiousoutput"))
- {
- copiousoutput = TRUE;
- if (entry)
- entry->copiousoutput = TRUE;
- }
- else if (!ascii_strncasecmp (field, "composetyped", 12))
- {
- /* this compare most occur before compose to match correctly */
- if (get_field_text (field + 12, entry ? &entry->composetypecommand : NULL,
- type, filename, line))
- composecommand = TRUE;
- }
- else if (!ascii_strncasecmp (field, "compose", 7))
- {
- if (get_field_text (field + 7, entry ? &entry->composecommand : NULL,
- type, filename, line))
- composecommand = TRUE;
- }
- else if (!ascii_strncasecmp (field, "print", 5))
- {
- if (get_field_text (field + 5, entry ? &entry->printcommand : NULL,
- type, filename, line))
- printcommand = TRUE;
- }
- else if (!ascii_strncasecmp (field, "edit", 4))
- {
- if (get_field_text (field + 4, entry ? &entry->editcommand : NULL,
- type, filename, line))
- editcommand = TRUE;
- }
- else if (!ascii_strncasecmp (field, "nametemplate", 12))
- {
- get_field_text (field + 12, entry ? &entry->nametemplate : NULL,
- type, filename, line);
- }
- else if (!ascii_strncasecmp (field, "x-convert", 9))
- {
- get_field_text (field + 9, entry ? &entry->convert : NULL,
- type, filename, line);
- }
- else if (!ascii_strncasecmp (field, "test", 4))
- {
- /*
- * This routine executes the given test command to determine
- * if this is the right entry.
- */
- char *test_command = NULL;
- size_t len;
-
- if (get_field_text (field + 4, &test_command, type, filename, line)
- && test_command)
- {
- len = mutt_strlen (test_command) + STRING;
- safe_realloc (&test_command, len);
- rfc1524_expand_command (a, a->filename, type, test_command, len);
- if (mutt_system (test_command))
- {
- /* a non-zero exit code means test failed */
- found = FALSE;
- }
- FREE (&test_command);
- }
- }
- } /* while (ch) */
-
- if (opt == M_AUTOVIEW)
- {
- if (!copiousoutput)
- found = FALSE;
+ while (ch) {
+ field = ch;
+ ch = get_field (ch);
+ debug_print (2, ("field: %s\n", field));
+
+ if (!ascii_strcasecmp (field, "needsterminal")) {
+ if (entry)
+ entry->needsterminal = TRUE;
+ }
+ else if (!ascii_strcasecmp (field, "copiousoutput")) {
+ copiousoutput = TRUE;
+ if (entry)
+ entry->copiousoutput = TRUE;
+ }
+ else if (!ascii_strncasecmp (field, "composetyped", 12)) {
+ /* this compare most occur before compose to match correctly */
+ if (get_field_text
+ (field + 12, entry ? &entry->composetypecommand : NULL, type,
+ filename, line))
+ composecommand = TRUE;
+ }
+ else if (!ascii_strncasecmp (field, "compose", 7)) {
+ if (get_field_text
+ (field + 7, entry ? &entry->composecommand : NULL, type,
+ filename, line))
+ composecommand = TRUE;
+ }
+ else if (!ascii_strncasecmp (field, "print", 5)) {
+ if (get_field_text (field + 5, entry ? &entry->printcommand : NULL,
+ type, filename, line))
+ printcommand = TRUE;
+ }
+ else if (!ascii_strncasecmp (field, "edit", 4)) {
+ if (get_field_text (field + 4, entry ? &entry->editcommand : NULL,
+ type, filename, line))
+ editcommand = TRUE;
+ }
+ else if (!ascii_strncasecmp (field, "nametemplate", 12)) {
+ get_field_text (field + 12, entry ? &entry->nametemplate : NULL,
+ type, filename, line);
+ }
+ else if (!ascii_strncasecmp (field, "x-convert", 9)) {
+ get_field_text (field + 9, entry ? &entry->convert : NULL,
+ type, filename, line);
+ }
+ else if (!ascii_strncasecmp (field, "test", 4)) {
+ /*
+ * This routine executes the given test command to determine
+ * if this is the right entry.
+ */
+ char *test_command = NULL;
+ size_t len;
+
+ if (get_field_text (field + 4, &test_command, type, filename, line)
+ && test_command) {
+ len = m_strlen(test_command) + STRING;
+ p_realloc(&test_command, len);
+ rfc1524_expand_command (a, a->filename, type, test_command, len);
+ if (mutt_system (test_command)) {
+ /* a non-zero exit code means test failed */
+ found = FALSE;
+ }
+ p_delete(&test_command);
+ }
+ }
+ } /* while (ch) */
+
+ if (opt == M_AUTOVIEW) {
+ if (!copiousoutput)
+ found = FALSE;
}
- else if (opt == M_COMPOSE)
- {
- if (!composecommand)
- found = FALSE;
+ else if (opt == M_COMPOSE) {
+ if (!composecommand)
+ found = FALSE;
}
- else if (opt == M_EDIT)
- {
- if (!editcommand)
- found = FALSE;
+ else if (opt == M_EDIT) {
+ if (!editcommand)
+ found = FALSE;
}
- else if (opt == M_PRINT)
- {
- if (!printcommand)
- found = FALSE;
+ else if (opt == M_PRINT) {
+ if (!printcommand)
+ found = FALSE;
}
-
- if (!found)
- {
- /* reset */
- if (entry)
- {
- FREE (&entry->command);
- FREE (&entry->composecommand);
- FREE (&entry->composetypecommand);
- FREE (&entry->editcommand);
- FREE (&entry->printcommand);
- FREE (&entry->nametemplate);
- FREE (&entry->convert);
- entry->needsterminal = 0;
- entry->copiousoutput = 0;
- }
+
+ if (!found) {
+ /* reset */
+ if (entry) {
+ p_delete(&entry->command);
+ p_delete(&entry->composecommand);
+ p_delete(&entry->composetypecommand);
+ p_delete(&entry->editcommand);
+ p_delete(&entry->printcommand);
+ p_delete(&entry->nametemplate);
+ p_delete(&entry->convert);
+ entry->needsterminal = 0;
+ entry->copiousoutput = 0;
+ }
}
- } /* while (!found && (buf = mutt_read_line ())) */
+ } /* while (!found && (buf = mutt_read_line ())) */
fclose (fp);
- } /* if ((fp = fopen ())) */
- FREE (&buf);
+ } /* if ((fp = fopen ())) */
+ p_delete(&buf);
return found;
}
-rfc1524_entry *rfc1524_new_entry(void)
+rfc1524_entry *rfc1524_new_entry (void)
{
- return (rfc1524_entry *)safe_calloc(1, sizeof(rfc1524_entry));
+ return p_new(rfc1524_entry, 1);
}
-void rfc1524_free_entry(rfc1524_entry **entry)
+void rfc1524_free_entry (rfc1524_entry ** entry)
{
rfc1524_entry *p = *entry;
- FREE (&p->command);
- FREE (&p->testcommand);
- FREE (&p->composecommand);
- FREE (&p->composetypecommand);
- FREE (&p->editcommand);
- FREE (&p->printcommand);
- FREE (&p->nametemplate);
- FREE (entry);
+ p_delete(&p->command);
+ p_delete(&p->testcommand);
+ p_delete(&p->composecommand);
+ p_delete(&p->composetypecommand);
+ p_delete(&p->editcommand);
+ p_delete(&p->printcommand);
+ p_delete(&p->nametemplate);
+ p_delete(entry);
}
/*
* in *entry, and returns 1. On failure (not found), returns 0.
* If entry == NULL just return 1 if the given type is found.
*/
-int rfc1524_mailcap_lookup (BODY *a, char *type, rfc1524_entry *entry, int opt)
+int rfc1524_mailcap_lookup (BODY * a, char *type, rfc1524_entry * entry,
+ int opt)
{
char path[_POSIX_PATH_MAX];
int x;
* and overriden by the MAILCAPS environment variable, and, just to be nice,
* we'll make it specifiable in .muttrc
*/
- if (!curr || !*curr)
- {
+ if (!curr || !*curr) {
mutt_error _("No mailcap path specified");
+
return 0;
}
mutt_check_lookup_list (a, type, SHORT_STRING);
- while (!found && *curr)
- {
+ while (!found && *curr) {
x = 0;
- while (*curr && *curr != ':' && x < sizeof (path) - 1)
- {
+ while (*curr && *curr != ':' && x < sizeof (path) - 1) {
path[x++] = *curr;
curr++;
}
if (!x)
continue;
-
+
path[x] = '\0';
mutt_expand_path (path, sizeof (path));
- dprint(2,(debugfile,"Checking mailcap file: %s\n",path));
+ debug_print (2, ("Checking mailcap file: %s\n", path));
found = rfc1524_mailcap_parse (a, path, type, entry, opt);
}
* Returns 1 if newfile specified
*/
-static void strnfcpy(char *d, char *s, size_t siz, size_t len)
+static void strnfcpy (char *d, char *s, size_t siz, size_t len)
{
- if(len > siz)
+ if (len > siz)
len = siz - 1;
- strfcpy(d, s, len);
+ m_strcpy(d, len, s);
}
int rfc1524_expand_filename (char *nametemplate,
- char *oldfile,
- char *newfile,
- size_t nflen)
+ char *oldfile, char *newfile, size_t nflen)
{
int i, j, k, ps, r;
char *s;
- short lmatch = 0, rmatch = 0;
+ short lmatch = 0, rmatch = 0;
char left[_POSIX_PATH_MAX];
char right[_POSIX_PATH_MAX];
-
+
newfile[0] = 0;
/* first, ignore leading path components.
*/
-
+
if (nametemplate && (s = strrchr (nametemplate, '/')))
nametemplate = s + 1;
if (oldfile && (s = strrchr (oldfile, '/')))
oldfile = s + 1;
-
- if (!nametemplate)
- {
+
+ if (!nametemplate) {
if (oldfile)
- strfcpy (newfile, oldfile, nflen);
+ m_strcpy(newfile, nflen, oldfile);
}
- else if (!oldfile)
- {
+ else if (!oldfile) {
mutt_expand_fmt (newfile, nflen, nametemplate, "mutt");
}
- else /* oldfile && nametemplate */
- {
+ else { /* oldfile && nametemplate */
+
/* first, compare everything left from the "%s"
* (if there is one).
*/
-
- lmatch = 1; ps = 0;
- for(i = 0; nametemplate[i]; i++)
- {
- if(nametemplate[i] == '%' && nametemplate[i+1] == 's')
- {
- ps = 1;
- break;
+
+ lmatch = 1;
+ ps = 0;
+ for (i = 0; nametemplate[i]; i++) {
+ if (nametemplate[i] == '%' && nametemplate[i + 1] == 's') {
+ ps = 1;
+ break;
}
/* note that the following will _not_ read beyond oldfile's end. */
- if(lmatch && nametemplate[i] != oldfile[i])
- lmatch = 0;
+ if (lmatch && nametemplate[i] != oldfile[i])
+ lmatch = 0;
}
- if(ps)
- {
-
+ if (ps) {
+
/* If we had a "%s", check the rest. */
-
+
/* now, for the right part: compare everything right from
* the "%s" to the final part of oldfile.
*
* must not be counted again. That's done by the
* condition (j >= (lmatch ? i : 0)).
*/
-
+
rmatch = 1;
- for(r = 0, j = mutt_strlen(oldfile) - 1, k = mutt_strlen(nametemplate) - 1 ;
- j >= (lmatch ? i : 0) && k >= i + 2;
- j--, k--)
- {
- if(nametemplate[k] != oldfile[j])
- {
- rmatch = 0;
- break;
- }
+ for (r = 0, j = m_strlen(oldfile) - 1, k =
+ m_strlen(nametemplate) - 1;
+ j >= (lmatch ? i : 0) && k >= i + 2; j--, k--) {
+ if (nametemplate[k] != oldfile[j]) {
+ rmatch = 0;
+ break;
+ }
}
-
+
/* Now, check if we had a full match. */
-
- if(k >= i + 2)
- rmatch = 0;
-
- if(lmatch) *left = 0;
- else strnfcpy(left, nametemplate, sizeof(left), i);
-
- if(rmatch) *right = 0;
- else strfcpy(right, nametemplate + i + 2, sizeof(right));
-
- snprintf(newfile, nflen, "%s%s%s", left, oldfile, right);
+
+ if (k >= i + 2)
+ rmatch = 0;
+
+ if (lmatch)
+ *left = 0;
+ else
+ strnfcpy (left, nametemplate, sizeof (left), i);
+
+ if (rmatch)
+ *right = 0;
+ else
+ m_strcpy(right, sizeof(right), nametemplate + i + 2);
+
+ snprintf (newfile, nflen, "%s%s%s", left, oldfile, right);
}
- else
- {
+ else {
/* no "%s" in the name template. */
- strfcpy(newfile, nametemplate, nflen);
+ m_strcpy(newfile, nflen, nametemplate);
}
}
-
- mutt_adv_mktemp(newfile, nflen);
- if(rmatch && lmatch)
+ mutt_adv_mktemp (NULL, newfile, nflen);
+
+ if (rmatch && lmatch)
return 0;
- else
+ else
return 1;
-
+
}
/* If rfc1524_expand_command() is used on a recv'd message, then
return 1;
if (!overwrite && access (newfile, F_OK) == 0)
return 2;
- if ((ofp = fopen (oldfile,"r")) == NULL)
+ if ((ofp = fopen (oldfile, "r")) == NULL)
return 3;
- if ((nfp = safe_fopen (newfile,"w")) == NULL)
- {
- fclose(ofp);
+ if ((nfp = safe_fopen (newfile, "w")) == NULL) {
+ fclose (ofp);
return 3;
}
- mutt_copy_stream (ofp,nfp);
+ mutt_copy_stream (ofp, nfp);
fclose (nfp);
fclose (ofp);
mutt_unlink (oldfile);