mutt stable branch with some hacks
at master 762 lines 20 kB view raw
1/* 2 * Copyright (C) 1996-2000,2002,2007 Michael R. Elkins <me@mutt.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19#if HAVE_CONFIG_H 20# include "config.h" 21#endif 22 23#include "mutt.h" 24#include "mutt_curses.h" 25#include "sort.h" 26#include "charset.h" 27#include "mutt_crypt.h" 28#include "mutt_idna.h" 29 30#include <ctype.h> 31#include <stdlib.h> 32#include <string.h> 33#include <locale.h> 34 35#ifdef HAVE_ALLOCA_H 36#include <alloca.h> 37#endif 38 39int mutt_is_mail_list (ADDRESS *addr) 40{ 41 if (!mutt_match_rx_list (addr->mailbox, UnMailLists)) 42 return mutt_match_rx_list (addr->mailbox, MailLists); 43 return 0; 44} 45 46int mutt_is_subscribed_list (ADDRESS *addr) 47{ 48 if (!mutt_match_rx_list (addr->mailbox, UnMailLists) 49 && !mutt_match_rx_list (addr->mailbox, UnSubscribedLists)) 50 return mutt_match_rx_list (addr->mailbox, SubscribedLists); 51 return 0; 52} 53 54/* Search for a mailing list in the list of addresses pointed to by adr. 55 * If one is found, print pfx and the name of the list into buf, then 56 * return 1. Otherwise, simply return 0. 57 */ 58static int 59check_for_mailing_list (ADDRESS *adr, char *pfx, char *buf, int buflen) 60{ 61 for (; adr; adr = adr->next) 62 { 63 if (mutt_is_subscribed_list (adr)) 64 { 65 if (pfx && buf && buflen) 66 snprintf (buf, buflen, "%s%s", pfx, mutt_get_name (adr)); 67 return 1; 68 } 69 } 70 return 0; 71} 72 73/* Search for a mailing list in the list of addresses pointed to by adr. 74 * If one is found, print the address of the list into buf, then return 1. 75 * Otherwise, simply return 0. 76 */ 77static int 78check_for_mailing_list_addr (ADDRESS *adr, char *buf, int buflen) 79{ 80 for (; adr; adr = adr->next) 81 { 82 if (mutt_is_subscribed_list (adr)) 83 { 84 if (buf && buflen) 85 snprintf (buf, buflen, "%s", adr->mailbox); 86 return 1; 87 } 88 } 89 return 0; 90} 91 92 93static int first_mailing_list (char *buf, size_t buflen, ADDRESS *a) 94{ 95 for (; a; a = a->next) 96 { 97 if (mutt_is_subscribed_list (a)) 98 { 99 mutt_save_path (buf, buflen, a); 100 return 1; 101 } 102 } 103 return 0; 104} 105 106static void make_from (ENVELOPE *hdr, char *buf, size_t len, int do_lists) 107{ 108 int me; 109 110 me = mutt_addr_is_user (hdr->from); 111 112 if (do_lists || me) 113 { 114 if (check_for_mailing_list (hdr->to, "To ", buf, len)) 115 return; 116 if (check_for_mailing_list (hdr->cc, "Cc ", buf, len)) 117 return; 118 } 119 120 if (me && hdr->to) 121 snprintf (buf, len, "To %s", mutt_get_name (hdr->to)); 122 else if (me && hdr->cc) 123 snprintf (buf, len, "Cc %s", mutt_get_name (hdr->cc)); 124 else if (me && hdr->bcc) 125 snprintf (buf, len, "Bcc %s", mutt_get_name (hdr->bcc)); 126 else if (hdr->from) 127 strfcpy (buf, mutt_get_name (hdr->from), len); 128 else 129 *buf = 0; 130} 131 132static void make_from_addr (ENVELOPE *hdr, char *buf, size_t len, int do_lists) 133{ 134 int me; 135 136 me = mutt_addr_is_user (hdr->from); 137 138 if (do_lists || me) 139 { 140 if (check_for_mailing_list_addr (hdr->to, buf, len)) 141 return; 142 if (check_for_mailing_list_addr (hdr->cc, buf, len)) 143 return; 144 } 145 146 if (me && hdr->to) 147 snprintf (buf, len, "%s", hdr->to->mailbox); 148 else if (me && hdr->cc) 149 snprintf (buf, len, "%s", hdr->cc->mailbox); 150 else if (hdr->from) 151 strfcpy (buf, hdr->from->mailbox, len); 152 else 153 *buf = 0; 154} 155 156static int user_in_addr (ADDRESS *a) 157{ 158 for (; a; a = a->next) 159 if (mutt_addr_is_user (a)) 160 return 1; 161 return 0; 162} 163 164/* Return values: 165 * 0: user is not in list 166 * 1: user is unique recipient 167 * 2: user is in the TO list 168 * 3: user is in the CC list 169 * 4: user is originator 170 * 5: sent to a subscribed mailinglist 171 */ 172int mutt_user_is_recipient (HEADER *h) 173{ 174 ENVELOPE *env = h->env; 175 176 if(!h->recip_valid) 177 { 178 h->recip_valid = 1; 179 180 if (mutt_addr_is_user (env->from)) 181 h->recipient = 4; 182 else if (user_in_addr (env->to)) 183 { 184 if (env->to->next || env->cc) 185 h->recipient = 2; /* non-unique recipient */ 186 else 187 h->recipient = 1; /* unique recipient */ 188 } 189 else if (user_in_addr (env->cc)) 190 h->recipient = 3; 191 else if (check_for_mailing_list (env->to, NULL, NULL, 0)) 192 h->recipient = 5; 193 else if (check_for_mailing_list (env->cc, NULL, NULL, 0)) 194 h->recipient = 5; 195 else 196 h->recipient = 0; 197 } 198 199 return h->recipient; 200} 201 202/* %a = address of author 203 * %A = reply-to address (if present; otherwise: address of author 204 * %b = filename of the originating folder 205 * %B = the list to which the letter was sent 206 * %c = size of message in bytes 207 * %C = current message number 208 * %d = date and time of message using $date_format and sender's timezone 209 * %D = date and time of message using $date_format and local timezone 210 * %e = current message number in thread 211 * %E = number of messages in current thread 212 * %f = entire from line 213 * %F = like %n, unless from self 214 * %i = message-id 215 * %l = number of lines in the message 216 * %L = like %F, except `lists' are displayed first 217 * %m = number of messages in the mailbox 218 * %n = name of author 219 * %N = score 220 * %O = like %L, except using address instead of name 221 * %P = progress indicator for builtin pager 222 * %r = comma separated list of To: recipients 223 * %R = comma separated list of Cc: recipients 224 * %s = subject 225 * %S = short message status (e.g., N/O/D/!/r/-) 226 * %t = `to:' field (recipients) 227 * %T = $to_chars 228 * %u = user (login) name of author 229 * %v = first name of author, unless from self 230 * %X = number of MIME attachments 231 * %y = `x-label:' field (if present) 232 * %Y = `x-label:' field (if present, tree unfolded, and != parent's x-label) 233 * %Z = status flags */ 234 235static const char * 236hdr_format_str (char *dest, 237 size_t destlen, 238 size_t col, 239 int cols, 240 char op, 241 const char *src, 242 const char *prefix, 243 const char *ifstring, 244 const char *elsestring, 245 unsigned long data, 246 format_flag flags) 247{ 248 struct hdr_format_info *hfi = (struct hdr_format_info *) data; 249 HEADER *hdr, *htmp; 250 CONTEXT *ctx; 251 char fmt[SHORT_STRING], buf2[LONG_STRING], ch, *p; 252 int do_locales, i; 253 int optional = (flags & MUTT_FORMAT_OPTIONAL); 254 int threads = ((Sort & SORT_MASK) == SORT_THREADS); 255 int is_index = (flags & MUTT_FORMAT_INDEX); 256#define THREAD_NEW (threads && hdr->collapsed && hdr->num_hidden > 1 && mutt_thread_contains_unread (ctx, hdr) == 1) 257#define THREAD_OLD (threads && hdr->collapsed && hdr->num_hidden > 1 && mutt_thread_contains_unread (ctx, hdr) == 2) 258 size_t len; 259 260 hdr = hfi->hdr; 261 ctx = hfi->ctx; 262 263 dest[0] = 0; 264 switch (op) 265 { 266 case 'A': 267 if(hdr->env->reply_to && hdr->env->reply_to->mailbox) 268 { 269 mutt_format_s (dest, destlen, prefix, mutt_addr_for_display (hdr->env->reply_to)); 270 break; 271 } 272 /* fall through if 'A' returns nothing */ 273 274 case 'a': 275 if(hdr->env->from && hdr->env->from->mailbox) 276 { 277 mutt_format_s (dest, destlen, prefix, mutt_addr_for_display (hdr->env->from)); 278 } 279 else 280 dest[0] = '\0'; 281 break; 282 283 case 'B': 284 if (!first_mailing_list (dest, destlen, hdr->env->to) && 285 !first_mailing_list (dest, destlen, hdr->env->cc)) 286 dest[0] = 0; 287 if (dest[0]) 288 { 289 strfcpy (buf2, dest, sizeof(buf2)); 290 mutt_format_s (dest, destlen, prefix, buf2); 291 break; 292 } 293 /* fall through if 'B' returns nothing */ 294 295 case 'b': 296 if(ctx) 297 { 298 if ((p = strrchr (ctx->path, '/'))) 299 strfcpy (dest, p + 1, destlen); 300 else 301 strfcpy (dest, ctx->path, destlen); 302 } 303 else 304 strfcpy(dest, "(null)", destlen); 305 strfcpy (buf2, dest, sizeof(buf2)); 306 mutt_format_s (dest, destlen, prefix, buf2); 307 break; 308 309 case 'c': 310 mutt_pretty_size (buf2, sizeof (buf2), (long) hdr->content->length); 311 mutt_format_s (dest, destlen, prefix, buf2); 312 break; 313 314 case 'C': 315 snprintf (fmt, sizeof (fmt), "%%%sd", prefix); 316 snprintf (dest, destlen, fmt, hdr->msgno + 1); 317 break; 318 319 case 'd': 320 case 'D': 321 case '{': 322 case '[': 323 case '(': 324 case '<': 325 326 /* preprocess $date_format to handle %Z */ 327 { 328 const char *cp; 329 struct tm *tm; 330 time_t T; 331 332 p = dest; 333 334 cp = (op == 'd' || op == 'D') ? (NONULL (DateFmt)) : src; 335 if (*cp == '!') 336 { 337 do_locales = 0; 338 cp++; 339 } 340 else 341 do_locales = 1; 342 343 len = destlen - 1; 344 while (len > 0 && (((op == 'd' || op == 'D') && *cp) || 345 (op == '{' && *cp != '}') || 346 (op == '[' && *cp != ']') || 347 (op == '(' && *cp != ')') || 348 (op == '<' && *cp != '>'))) 349 { 350 if (*cp == '%') 351 { 352 cp++; 353 if ((*cp == 'Z' || *cp == 'z') && (op == 'd' || op == '{')) 354 { 355 if (len >= 5) 356 { 357 sprintf (p, "%c%02u%02u", hdr->zoccident ? '-' : '+', 358 hdr->zhours, hdr->zminutes); 359 p += 5; 360 len -= 5; 361 } 362 else 363 break; /* not enough space left */ 364 } 365 else 366 { 367 if (len >= 2) 368 { 369 *p++ = '%'; 370 *p++ = *cp; 371 len -= 2; 372 } 373 else 374 break; /* not enough space */ 375 } 376 cp++; 377 } 378 else 379 { 380 *p++ = *cp++; 381 len--; 382 } 383 } 384 *p = 0; 385 386 if (op == '[' || op == 'D') 387 tm = localtime (&hdr->date_sent); 388 else if (op == '(') 389 tm = localtime (&hdr->received); 390 else if (op == '<') 391 { 392 T = time (NULL); 393 tm = localtime (&T); 394 } 395 else 396 { 397 /* restore sender's time zone */ 398 T = hdr->date_sent; 399 if (hdr->zoccident) 400 T -= (hdr->zhours * 3600 + hdr->zminutes * 60); 401 else 402 T += (hdr->zhours * 3600 + hdr->zminutes * 60); 403 tm = gmtime (&T); 404 } 405 406 if (!do_locales) 407 setlocale (LC_TIME, "C"); 408 strftime (buf2, sizeof (buf2), dest, tm); 409 if (!do_locales) 410 setlocale (LC_TIME, ""); 411 412 mutt_format_s (dest, destlen, prefix, buf2); 413 if (len > 0 && op != 'd' && op != 'D') /* Skip ending op */ 414 src = cp + 1; 415 } 416 break; 417 418 case 'e': 419 snprintf (fmt, sizeof (fmt), "%%%sd", prefix); 420 snprintf (dest, destlen, fmt, mutt_messages_in_thread(ctx, hdr, 1)); 421 break; 422 423 case 'E': 424 if (!optional) 425 { 426 snprintf (fmt, sizeof (fmt), "%%%sd", prefix); 427 snprintf (dest, destlen, fmt, mutt_messages_in_thread(ctx, hdr, 0)); 428 } 429 else if (mutt_messages_in_thread(ctx, hdr, 0) <= 1) 430 optional = 0; 431 break; 432 433 case 'f': 434 buf2[0] = 0; 435 rfc822_write_address (buf2, sizeof (buf2), hdr->env->from, 1); 436 mutt_format_s (dest, destlen, prefix, buf2); 437 break; 438 439 case 'F': 440 if (!optional) 441 { 442 make_from (hdr->env, buf2, sizeof (buf2), 0); 443 mutt_format_s (dest, destlen, prefix, buf2); 444 } 445 else if (mutt_addr_is_user (hdr->env->from)) 446 optional = 0; 447 break; 448 449 case 'H': 450 /* (Hormel) spam score */ 451 if (optional) 452 optional = hdr->env->spam ? 1 : 0; 453 454 if (hdr->env->spam) 455 mutt_format_s (dest, destlen, prefix, NONULL (hdr->env->spam->data)); 456 else 457 mutt_format_s (dest, destlen, prefix, ""); 458 459 break; 460 461 case 'i': 462 mutt_format_s (dest, destlen, prefix, hdr->env->message_id ? hdr->env->message_id : "<no.id>"); 463 break; 464 465 case 'l': 466 if (!optional) 467 { 468 snprintf (fmt, sizeof (fmt), "%%%sd", prefix); 469 snprintf (dest, destlen, fmt, (int) hdr->lines); 470 } 471 else if (hdr->lines <= 0) 472 optional = 0; 473 break; 474 475 case 'L': 476 if (!optional) 477 { 478 make_from (hdr->env, buf2, sizeof (buf2), 1); 479 mutt_format_s (dest, destlen, prefix, buf2); 480 } 481 else if (!check_for_mailing_list (hdr->env->to, NULL, NULL, 0) && 482 !check_for_mailing_list (hdr->env->cc, NULL, NULL, 0)) 483 { 484 optional = 0; 485 } 486 break; 487 488 case 'm': 489 if(ctx) 490 { 491 snprintf (fmt, sizeof (fmt), "%%%sd", prefix); 492 snprintf (dest, destlen, fmt, ctx->msgcount); 493 } 494 else 495 strfcpy(dest, "(null)", destlen); 496 break; 497 498 case 'n': 499 mutt_format_s (dest, destlen, prefix, mutt_get_name (hdr->env->from)); 500 break; 501 502 case 'N': 503 if (!optional) 504 { 505 snprintf (fmt, sizeof (fmt), "%%%sd", prefix); 506 snprintf (dest, destlen, fmt, hdr->score); 507 } 508 else 509 { 510 if (hdr->score == 0) 511 optional = 0; 512 } 513 break; 514 515 case 'O': 516 if (!optional) 517 { 518 make_from_addr (hdr->env, buf2, sizeof (buf2), 1); 519 if (!option (OPTSAVEADDRESS) && (p = strpbrk (buf2, "%@"))) 520 *p = 0; 521 mutt_format_s (dest, destlen, prefix, buf2); 522 } 523 else if (!check_for_mailing_list_addr (hdr->env->to, NULL, 0) && 524 !check_for_mailing_list_addr (hdr->env->cc, NULL, 0)) 525 { 526 optional = 0; 527 } 528 break; 529 530 case 'M': 531 snprintf (fmt, sizeof (fmt), "%%%sd", prefix); 532 if (!optional) 533 { 534 if (threads && is_index && hdr->collapsed && hdr->num_hidden > 1) 535 snprintf (dest, destlen, fmt, hdr->num_hidden); 536 else if (is_index && threads) 537 mutt_format_s (dest, destlen, prefix, " "); 538 else 539 *dest = '\0'; 540 } 541 else 542 { 543 if (!(threads && is_index && hdr->collapsed && hdr->num_hidden > 1)) 544 optional = 0; 545 } 546 break; 547 548 case 'P': 549 strfcpy(dest, NONULL(hfi->pager_progress), destlen); 550 break; 551 552 case 'r': 553 buf2[0] = 0; 554 rfc822_write_address(buf2, sizeof(buf2), hdr->env->to, 1); 555 if (optional && buf2[0] == '\0') 556 optional = 0; 557 mutt_format_s (dest, destlen, prefix, buf2); 558 break; 559 560 case 'R': 561 buf2[0] = 0; 562 rfc822_write_address(buf2, sizeof(buf2), hdr->env->cc, 1); 563 if (optional && buf2[0] == '\0') 564 optional = 0; 565 mutt_format_s (dest, destlen, prefix, buf2); 566 break; 567 568 case 's': 569 570 if (flags & MUTT_FORMAT_TREE && !hdr->collapsed) 571 { 572 if (flags & MUTT_FORMAT_FORCESUBJ) 573 { 574 mutt_format_s (dest, destlen, "", NONULL (hdr->env->subject)); 575 snprintf (buf2, sizeof (buf2), "%s%s", hdr->tree, dest); 576 mutt_format_s_tree (dest, destlen, prefix, buf2); 577 } 578 else 579 mutt_format_s_tree (dest, destlen, prefix, hdr->tree); 580 } 581 else 582 mutt_format_s (dest, destlen, prefix, NONULL (hdr->env->subject)); 583 break; 584 585 case 'S': 586 if (hdr->deleted) 587 ch = 'D'; 588 else if (hdr->attach_del) 589 ch = 'd'; 590 else if (hdr->tagged) 591 ch = '*'; 592 else if (hdr->flagged) 593 ch = '!'; 594 else if (hdr->replied) 595 ch = 'r'; 596 else if (hdr->read && (ctx && ctx->msgnotreadyet != hdr->msgno)) 597 ch = '-'; 598 else if (hdr->old) 599 ch = 'O'; 600 else 601 ch = 'N'; 602 603 /* FOO - this is probably unsafe, but we are not likely to have such 604 a short string passed into this routine */ 605 *dest = ch; 606 *(dest + 1) = 0; 607 break; 608 609 case 't': 610 buf2[0] = 0; 611 if (!check_for_mailing_list (hdr->env->to, "To ", buf2, sizeof (buf2)) && 612 !check_for_mailing_list (hdr->env->cc, "Cc ", buf2, sizeof (buf2))) 613 { 614 if (hdr->env->to) 615 snprintf (buf2, sizeof (buf2), "To %s", mutt_get_name (hdr->env->to)); 616 else if (hdr->env->cc) 617 snprintf (buf2, sizeof (buf2), "Cc %s", mutt_get_name (hdr->env->cc)); 618 } 619 mutt_format_s (dest, destlen, prefix, buf2); 620 break; 621 622 case 'T': 623 snprintf (fmt, sizeof (fmt), "%%%ss", prefix); 624 snprintf (dest, destlen, fmt, 625 (Tochars && ((i = mutt_user_is_recipient (hdr))) < Tochars->len) ? Tochars->chars[i] : " "); 626 break; 627 628 case 'u': 629 if (hdr->env->from && hdr->env->from->mailbox) 630 { 631 strfcpy (buf2, mutt_addr_for_display (hdr->env->from), sizeof (buf2)); 632 if ((p = strpbrk (buf2, "%@"))) 633 *p = 0; 634 } 635 else 636 buf2[0] = 0; 637 mutt_format_s (dest, destlen, prefix, buf2); 638 break; 639 640 case 'v': 641 if (mutt_addr_is_user (hdr->env->from)) 642 { 643 if (hdr->env->to) 644 mutt_format_s (buf2, sizeof (buf2), prefix, mutt_get_name (hdr->env->to)); 645 else if (hdr->env->cc) 646 mutt_format_s (buf2, sizeof (buf2), prefix, mutt_get_name (hdr->env->cc)); 647 else 648 *buf2 = 0; 649 } 650 else 651 mutt_format_s (buf2, sizeof (buf2), prefix, mutt_get_name (hdr->env->from)); 652 if ((p = strpbrk (buf2, " %@"))) 653 *p = 0; 654 mutt_format_s (dest, destlen, prefix, buf2); 655 break; 656 657 case 'Z': 658 659 ch = ' '; 660 661 if (WithCrypto && hdr->security & GOODSIGN) 662 ch = 'S'; 663 else if (WithCrypto && hdr->security & ENCRYPT) 664 ch = 'P'; 665 else if (WithCrypto && hdr->security & SIGN) 666 ch = 's'; 667 else if ((WithCrypto & APPLICATION_PGP) && hdr->security & PGPKEY) 668 ch = 'K'; 669 670 snprintf (buf2, sizeof (buf2), 671 "%c%c%s", (THREAD_NEW ? 'n' : (THREAD_OLD ? 'o' : 672 ((hdr->read && (ctx && ctx->msgnotreadyet != hdr->msgno)) 673 ? (hdr->replied ? 'r' : ' ') : (hdr->old ? 'O' : 'N')))), 674 hdr->deleted ? 'D' : (hdr->attach_del ? 'd' : ch), 675 hdr->tagged ? "*" : 676 (hdr->flagged ? "!" : 677 (Tochars && ((i = mutt_user_is_recipient (hdr)) < Tochars->len) ? Tochars->chars[i] : " "))); 678 mutt_format_s (dest, destlen, prefix, buf2); 679 break; 680 681 case 'X': 682 { 683 int count = mutt_count_body_parts (ctx, hdr); 684 685 /* The recursion allows messages without depth to return 0. */ 686 if (optional) 687 optional = count != 0; 688 689 snprintf (fmt, sizeof (fmt), "%%%sd", prefix); 690 snprintf (dest, destlen, fmt, count); 691 } 692 break; 693 694 case 'y': 695 if (optional) 696 optional = hdr->env->x_label ? 1 : 0; 697 698 mutt_format_s (dest, destlen, prefix, NONULL (hdr->env->x_label)); 699 break; 700 701 case 'Y': 702 if (hdr->env->x_label) 703 { 704 i = 1; /* reduce reuse recycle */ 705 htmp = NULL; 706 if (flags & MUTT_FORMAT_TREE 707 && (hdr->thread->prev && hdr->thread->prev->message 708 && hdr->thread->prev->message->env->x_label)) 709 htmp = hdr->thread->prev->message; 710 else if (flags & MUTT_FORMAT_TREE 711 && (hdr->thread->parent && hdr->thread->parent->message 712 && hdr->thread->parent->message->env->x_label)) 713 htmp = hdr->thread->parent->message; 714 if (htmp && mutt_strcasecmp (hdr->env->x_label, 715 htmp->env->x_label) == 0) 716 i = 0; 717 } 718 else 719 i = 0; 720 721 if (optional) 722 optional = i; 723 724 if (i) 725 mutt_format_s (dest, destlen, prefix, NONULL (hdr->env->x_label)); 726 else 727 mutt_format_s (dest, destlen, prefix, ""); 728 729 break; 730 731 default: 732 snprintf (dest, destlen, "%%%s%c", prefix, op); 733 break; 734 } 735 736 if (optional) 737 mutt_FormatString (dest, destlen, col, cols, ifstring, hdr_format_str, (unsigned long) hfi, flags); 738 else if (flags & MUTT_FORMAT_OPTIONAL) 739 mutt_FormatString (dest, destlen, col, cols, elsestring, hdr_format_str, (unsigned long) hfi, flags); 740 741 return (src); 742#undef THREAD_NEW 743#undef THREAD_OLD 744} 745 746void 747_mutt_make_string (char *dest, size_t destlen, const char *s, CONTEXT *ctx, HEADER *hdr, format_flag flags) 748{ 749 struct hdr_format_info hfi; 750 751 hfi.hdr = hdr; 752 hfi.ctx = ctx; 753 hfi.pager_progress = 0; 754 755 mutt_FormatString (dest, destlen, 0, MuttIndexWindow->cols, s, hdr_format_str, (unsigned long) &hfi, flags); 756} 757 758void 759mutt_make_string_info (char *dst, size_t dstlen, int cols, const char *s, struct hdr_format_info *hfi, format_flag flags) 760{ 761 mutt_FormatString (dst, dstlen, 0, cols, s, hdr_format_str, (unsigned long) hfi, flags); 762}