#include <grp.h>
#include <pwd.h>
-#include <utime.h>
#include <lib-mime/mime.h>
#include <lib-ui/curses.h>
/* if s is an url, only collapse path component */
if (scheme != U_UNKNOWN) {
p = strchr (s, ':') + 1;
- if (!strncmp (p, "//", 2))
+ if (!m_strncmp (p, "//", 2))
q = strchr (p + 2, '/');
if (!q)
q = strchr (p, '\0');
}
}
-void
-mutt_expand_file_fmt(char *dst, ssize_t n, const char *fmt, const char *src)
-{
- char tmp[LONG_STRING];
- mutt_quote_filename(tmp, sizeof(tmp), src);
- m_file_fmt(dst, n, fmt, tmp);
-}
-
/* return 0 on success, -1 on abort, 1 on error */
int mutt_check_overwrite (const char *attname, const char *path,
char *fname, ssize_t flen, int *append,
}
}
-void mutt_FormatString (char *dest, /* output buffer */
- ssize_t destlen, /* output buffer len */
- const char *src, /* template string */
- format_t * callback, /* callback for processing */
- unsigned long data, /* callback data */
- format_flag flags)
-{ /* callback flags */
- char prefix[SHORT_STRING], buf[LONG_STRING], *cp, *wptr = dest, ch;
- char ifstring[SHORT_STRING], elsestring[SHORT_STRING];
- ssize_t wlen, wid, count, col, len;
-
- prefix[0] = '\0';
- destlen--; /* save room for the terminal \0 */
- wlen = (flags & M_FORMAT_ARROWCURSOR && option (OPTARROWCURSOR)) ? 3 : 0;
- col = wlen;
-
- while (*src && wlen < destlen) {
- if (*src == '%') {
- if (*++src == '%') {
- *wptr++ = '%';
- wlen++;
- col++;
- src++;
- continue;
- }
+ssize_t m_strformat(char *dst, ssize_t dlen, const char *fmt,
+ format_t *callback, anytype cdata, format_flag flags)
+{
+ ssize_t pos = flags & M_FORMAT_ARROWCURSOR ? 3 : 0;
- if (*src == '?') {
- flags |= M_FORMAT_OPTIONAL;
- src++;
- }
- else {
- flags &= ~M_FORMAT_OPTIONAL;
-
- /* eat the format string */
- cp = prefix;
- count = 0;
- while (count < ssizeof (prefix) &&
- (isdigit ((unsigned char) *src) || *src == '.' || *src == '-'))
- {
- *cp++ = *src++;
- count++;
- }
- *cp = 0;
- }
+ if (dlen >= 0)
+ *dst = '\0';
- if (!*src)
- break; /* bad format */
+ while (*fmt) {
+ int ch;
- ch = *src++; /* save the character to switch on */
+ if (*fmt == '%') {
+ char ifstr[STRING], elstr[STRING], prefix[STRING];
- if (flags & M_FORMAT_OPTIONAL) {
- if (*src != '?')
- break; /* bad format */
- src++;
+ *ifstr = *elstr = *prefix = '\0';
- /* eat the `if' part of the string */
- cp = ifstring;
- count = 0;
- while (count < ssizeof (ifstring) && *src && *src != '?'
- && *src != '&') {
- *cp++ = *src++;
- count++;
- }
- *cp = 0;
-
- /* eat the `else' part of the string (optional) */
- if (*src == '&')
- src++; /* skip the & */
- cp = elsestring;
- count = 0;
- while (count < ssizeof (elsestring) && *src && *src != '?') {
- *cp++ = *src++;
- count++;
- }
- *cp = 0;
+ if (*++fmt == '%') {
+ pos += m_strputc(dst + pos, dlen - pos, *fmt++);
+ continue;
+ }
- if (!*src)
- break; /* bad format */
+ if (*fmt == '?') {
+ flags |= M_FORMAT_OPTIONAL;
+ fmt++;
+ } else {
+ ssize_t pfxlen;
+ flags &= ~M_FORMAT_OPTIONAL;
- src++; /* move past the trailing `?' */
- }
+ /* eat the format string */
+ pfxlen = strspn(fmt, "0123456789.-");
+ m_strncpy(prefix, sizeof(prefix), fmt, pfxlen);
+ fmt += pfxlen;
+ }
- /* handle generic cases first */
- if (ch == '>') {
- /* right justify to EOL */
- ch = *src++; /* pad char */
- /* calculate space left on line. if we've already written more data
- than will fit on the line, ignore the rest of the line */
- if (DrawFullLine || option (OPTSTATUSONTOP))
- count = (COLS < destlen ? COLS : destlen);
- else
- count = ((COLS - SW) < destlen ? (COLS - SW) : destlen);
- if (count > col) {
- count -= col; /* how many columns left on this line */
- mutt_FormatString (buf, sizeof (buf), src, callback, data, flags);
- wid = m_strlen(buf);
- if (count > wid) {
- count -= wid; /* how many chars to pad */
- memset (wptr, ch, count);
- wptr += count;
- col += count;
- }
- if (wid + wlen > destlen)
- len = destlen - wlen;
- else
- len = wid;
- memcpy (wptr, buf, len);
- wptr += len;
- wlen += len;
- col += mutt_strwidth (buf);
- }
- break; /* skip rest of input */
- }
- else if (ch == '|') {
- /* pad to EOL */
- ch = *src++;
- if (destlen > COLS)
- destlen = COLS;
- if (destlen > wlen) {
- count = destlen - wlen;
- memset (wptr, ch, count);
- wptr += count;
- }
- break; /* skip rest of input */
- }
- else {
- short lower = 0;
- short nodots = 0;
+ /* save the character to switch on */
+ if (!(ch = *fmt++))
+ break;
- while (ch == '_' || ch == ':') {
- if (ch == '_')
- lower = 1;
- else if (ch == ':')
- nodots = 1;
+ if (flags & M_FORMAT_OPTIONAL) {
+ ssize_t iflen;
+ const char *p;
- ch = *src++;
- }
+ if (*fmt++ != '?')
+ break; /* bad format */
- /* use callback function to handle this case */
- src =
- callback (buf, sizeof (buf), ch, src, prefix, ifstring, elsestring,
- data, flags);
+ /* eat the `if' part of the string */
+ iflen = strcspn(fmt, "?&");
+ m_strncpy(ifstr, ssizeof(ifstr), fmt, iflen);
+ fmt += iflen;
- if (lower)
- m_strtolower(buf);
- if (nodots) {
- char *p = buf;
+ /* eat the `else' part of the string (optional) */
+ if (*fmt == '&')
+ fmt++; /* skip the & */
- for (; *p; p++)
- if (*p == '.')
- *p = '_';
+ p = m_strchrnul(fmt, '?');
+ m_strncpy(elstr, ssizeof(elstr), fmt, p - fmt);
+ fmt = p;
+
+ if (!*fmt++) /* move past the trailing `?' */
+ break; /* bad format */
+ }
+
+ switch (ch) {
+ ssize_t col;
+ char lower, nodots, buf[LONG_STRING];
+
+ case '>': /* right justify to EOL */
+ col = mutt_strwidth(dst);
+
+ ch = *fmt++; /* pad char */
+
+ if (COLS - SW > col) {
+ m_strformat(buf, sizeof(buf), fmt, callback, cdata, flags);
+ pos += m_strpad(dst + pos, dlen - pos, ch,
+ COLS - SW - col - mutt_strwidth(buf));
+ pos += m_strcpy(dst + pos, dlen - pos, buf);
+ }
+ return pos; /* skip rest of input */
+
+ case '|': /* pad to EOL */
+ return pos + m_strpad(dst + pos, dlen - pos, *fmt,
+ COLS - SW - mutt_strwidth(dst));
+
+ default:
+ lower = nodots = 0;
+
+ while (ch == '_' || ch == ':') {
+ lower |= ch == '_';
+ nodots |= ch == ':';
+ ch = *fmt++;
+ }
+
+ /* use callback function to handle this case */
+ fmt = callback(buf, sizeof (buf), ch, fmt, prefix,
+ ifstr, elstr, cdata, flags);
+
+ if (lower)
+ m_strtolower(buf);
+
+ if (nodots) {
+ char *p;
+
+ for (p = buf; *p; p++) {
+ if (*p == '.')
+ *p = '_';
+ }
+ }
+
+ pos += m_strcpy(dst + pos, dlen - pos, buf);
+ break;
+ }
+ continue;
}
- if ((len = m_strlen(buf)) + wlen > destlen)
- len = (destlen - wlen > 0) ? (destlen - wlen) : 0;
+ if (*fmt == '\\') {
+ if (!*++fmt)
+ break;
+ switch ((ch = *fmt++)) {
+ case 'n': pos += m_strputc(dst + pos, dlen - pos, '\n'); break;
+ case 't': pos += m_strputc(dst + pos, dlen - pos, '\t'); break;
+ case 'r': pos += m_strputc(dst + pos, dlen - pos, '\r'); break;
+ case 'f': pos += m_strputc(dst + pos, dlen - pos, '\f'); break;
+ case 'v': pos += m_strputc(dst + pos, dlen - pos, '\v'); break;
+ default: pos += m_strputc(dst + pos, dlen - pos, ch); break;
+ }
+ } else {
+ ssize_t len = strcspn(fmt, "%\\");
- memcpy (wptr, buf, len);
- wptr += len;
- wlen += len;
- col += mutt_strwidth (buf);
- }
- }
- else if (*src == '\\') {
- if (!*++src)
- break;
- switch (*src) {
- case 'n':
- *wptr = '\n';
- break;
- case 't':
- *wptr = '\t';
- break;
- case 'r':
- *wptr = '\r';
- break;
- case 'f':
- *wptr = '\f';
- break;
- case 'v':
- *wptr = '\v';
- break;
- default:
- *wptr = *src;
- break;
- }
- src++;
- wptr++;
- wlen++;
- col++;
+ pos += m_strncpy(dst + pos, dlen - pos, fmt, len);
+ fmt += len;
+ }
}
- else {
- unsigned int bar = strcspn(src, "%\\");
- char *bar2 = p_dupstr(src, bar);
- while (bar--) {
- *wptr++ = *src++;
- wlen++;
- }
- col += mutt_strwidth (bar2);
- p_delete(&bar2);
- }
- }
- *wptr = 0;
+ return pos;
}
/* returns 0 if OK to proceed, -1 to abort, 1 to retry */
sleep(MAX(s, SleepTime));
}
-/* Decrease a file's modification time by 1 second */
-time_t mutt_decrease_mtime (const char *f, struct stat *st)
-{
- struct utimbuf utim;
- struct stat _st;
- time_t mtime;
-
- if (!st) {
- if (stat (f, &_st) == -1)
- return -1;
- st = &_st;
- }
-
- if ((mtime = st->st_mtime) == time (NULL)) {
- mtime -= 1;
- utim.actime = mtime;
- utim.modtime = mtime;
- utime (f, &utim);
- }
-
- return mtime;
-}
-
const char *mutt_make_version (int full)
{
static char vstring[STRING];
return vstring;
}
-int mutt_match_spam_list (const char *s, rx_t * l, char *text, int x)
-{
- static regmatch_t *pmatch = NULL;
- static int nmatch = 0;
- int i, n, tlen;
- char *p;
-
- if (!s)
- return 0;
-
- tlen = 0;
-
- for (; l; l = l->next) {
- /* If this pattern needs more matches, expand pmatch. */
- if (l->nmatch > nmatch) {
- p_realloc(&pmatch, l->nmatch);
- nmatch = l->nmatch;
- }
-
- /* Does this pattern match? */
- if (regexec(l->rx, s, l->nmatch, (regmatch_t *)pmatch, (int) 0) == 0) {
- /* Copy template into text, with substitutions. */
- for (p = l->template; *p;) {
- if (*p == '%') {
- n = atoi (++p); /* find pmatch index */
- while (isdigit ((unsigned char) *p))
- ++p; /* skip subst token */
- for (i = pmatch[n].rm_so; (i < pmatch[n].rm_eo) && (tlen < x); i++)
- text[tlen++] = s[i];
- }
- else {
- text[tlen++] = *p++;
- }
- }
- text[tlen] = '\0';
- return 1;
- }
- }
-
- return 0;
-}
-
/* return 1 if address lists are strictly identical */
static int mutt_cmp_addr (const address_t * a, const address_t * b)
{
if (!*tok->dptr)
return -1; /* premature end of token */
mutt_buffer_addch(dest,
- (ascii_toupper(*tok->dptr) - 'A' + 1) & 0x7f);
+ (toupper((unsigned char)*tok->dptr) - 'A' + 1) & 0x7f);
tok->dptr++;
break;
case 'r':
mutt_buffer_addch(dest, '\033');
} else
if (isalpha((unsigned char)ch)) {
- mutt_buffer_addch(dest, ascii_toupper(ch) - 'A' + 1);
+ mutt_buffer_addch(dest, toupper((unsigned char)ch) - 'A' + 1);
} else {
mutt_buffer_addch(dest, '^');
mutt_buffer_addch(dest, ch);
/* read line */
p_clear(&expn, 1);
expn.data = mutt_read_line(NULL, &expn.dsize, fp, &line);
- fclose(fp);
+ m_fclose(&fp);
mutt_wait_filter(pid);
/* if we got output, make a new string consiting of the shell ouptput
tok->dsize = expnlen + m_strlen(tok->dptr) + 1;
ptr = xmalloc(tok->dsize);
memcpy(ptr, expn.data, expnlen);
- strcpy(ptr + expnlen, tok->dptr); /* __STRCPY_CHECKED__ */
+ m_strcpy(ptr + expnlen, tok->dsize - expnlen, tok->dptr);
if (tok->destroy)
p_delete(&tok->data);
tok->data = ptr;