home *** CD-ROM | disk | FTP | other *** search
- /* hdrs.c (c) copyright 1986 (Dan Heller) */
-
- /*
- * Routines that deal with message headers inside messages
- * msg_get(n, from, count) -- get the From_ line in msg n into "from".
- * header_field(n, str) -- get the header named "str" from msg n.
- * do_hdrs(argc, argv, list) -- diplay message headers.
- * specl_hdrs(argv, list) -- display msgs that share common attributes.
- * compose_hdr(cnt) -- compose a message header from msg n.
- * reply_to(n, all, buf) -- construct a header based on the To: header of n.
- * subject_to(n, buf) -- get the subject for replying to msg n.
- * cc_to(n, buf) -- construct a Cc header based on the Cc of message n.
- */
- #include "mush.h"
-
- #ifdef SUNTOOL
- #define highlight(win,x,y,s) \
- (void) (pw_text(win,x,y, PIX_SRC, mush_font, s), \
- pw_text(win,x+1,y, \
- (ison(glob_flags, REV_VIDEO))? PIX_NOT(PIX_SRC): PIX_SRC|PIX_DST, \
- mush_font, s))
- #endif /* SUNTOOL */
-
- /*
- * Get a message from the current folder by its offset.
- * Copy the From_ line to the second argument if the third arg > 0,
- * and return the second argument, or NULL on an error.
- */
- char *
- msg_get(n, from, count)
- int n, count;
- char *from;
- {
- if (fseek(tmpf, msg[n].m_offset, L_SET) == -1) {
- error("fseek in %s (msg %d, folder=%s)", tempfile, n+1, mailfile);
- turnon(glob_flags, READ_ONLY);
- return NULL;
- }
- if (count)
- #ifndef MSG_SEPARATOR
- return fgets(from, count, tmpf);
- #else
- *from = '\0';
- #endif
- return from;
- }
-
- /*
- * get which message via the offset and search for the headers which
- * match the string "str". there may be more than one of a field (like Cc:)
- * so get them all and "cat" them together into the static buffer
- * "buf" and return its address.
- */
- char *
- header_field(n, str)
- char *str;
- {
- static char buf[HDRSIZ];
- char tmp[HDRSIZ];
- register char *p, *p2, *b = buf;
- int contd_hdr; /* true if next line is a continuation of the hdr we want */
-
- /* use msg_get as a test for fseek() -- don't let it fgets() (pass 0) */
- if (!msg_get(n, tmp, 0))
- return NULL;
- *b = 0;
- while((p = fgets(tmp, sizeof(tmp), tmpf)) && *p != '\n') {
- if (*p != ' ' && *p != '\t') {
- contd_hdr = 0;
- /* strcmp ignoring case */
- for(p2 = str; *p && *p2 && lower(*p2) == lower(*p); ++p, ++p2);
- /* MATCH is true if p2 is at the end of str and *p is ':' */
- if (*p2 || *p++ != ':')
- continue;
- else
- contd_hdr = 1;
- if (b > buf && (b - buf) < sizeof buf - 2)
- *b++ = ',';
- } else if (!contd_hdr)
- continue;
- skipspaces(0);
- (void) no_newln(p);
- if (strlen(p) + (b - buf) < sizeof buf - 1) {
- if (b > buf)
- *b++ = ' ';
- b += Strcpy(b, p);
- }
- }
- if (*--b == ',')
- *b = 0;
- return (*buf)? buf: NULL;
- }
-
- do_hdrs(argc, argv, list)
- register char **argv, list[];
- {
- register int pageful = 0;
- SIGRET (*oldint)(), (*oldquit)();
- int show_deleted, srch = 1; /* search forward by default */
- static int cnt, oldscrn = 1;
- register char *p;
- char first_char = (argc) ? **argv: 'h';
-
- if (argc > 1 && !strcmp(argv[1], "-?"))
- return help(0, "headers", cmd_help);
-
- if (!msg_cnt) {
- if (ison(glob_flags, DO_PIPE))
- return 0;
- #ifdef CURSES
- if (iscurses)
- clear();
- #endif /* CURSES */
- #ifdef SUNTOOL
- if (istool)
- mail_status(0);
- #endif /* SUNTOOL */
- return 0;
- }
- if (first_char == ':' || (argc > 1 && argv[1][0] == ':')) {
- if (first_char != ':')
- argv++;
- return specl_hdrs(argv, list);
- } else if (argc > 1 && !strncmp(argv[1], "-H:", 3)) {
- argv[1][0] = ':';
- argv[1][1] = argv[1][3];
- argv[1][2] = 0;
- return specl_hdrs(&argv[1], list);
- }
-
- on_intr();
-
- if (argc && (argv[0][1] == '-' || argc > 1 && !strcmp(argv[1], "-"))) {
- cnt = max(n_array[0], 0);
- srch = -1; /* search backwards */
- } else if (argc && (argv[0][1] == '+' ||
- argc > 1 && !strcmp(argv[1], "+")) ||
- first_char == 'z' && !argv[1]) {
- if (msg_cnt > screen)
- cnt = min(msg_cnt - screen, n_array[0] + screen);
- else
- cnt = 0;
- } else if (argc && *++argv &&
- (isdigit(**argv) || **argv == '^' ||
- **argv == '$' || **argv == '.') ||
- ison(glob_flags, IS_PIPE)) {
- /* if we're coming from a pipe, start display at the first msg bit
- * set in the msg_list
- */
- int fnd;
- if (ison(glob_flags, IS_PIPE)) {
- if (isoff(glob_flags, DO_PIPE))
- for (fnd = 0; fnd < msg_cnt; fnd++)
- if (msg_bit(list, fnd))
- wprint("%s\n", compose_hdr(fnd));
- off_intr();
- return 0;
- }
- /* if a number was given, use it */
- if (!(fnd = chk_msg(*argv))) {
- off_intr();
- return -1;
- }
- for (cnt = fnd - 1; cnt > 0 && cnt + screen > msg_cnt; cnt--)
- ;
- } else if (current_msg < n_array[0] || current_msg > n_array[oldscrn-1] ||
- (iscurses || oldscrn != screen) &&
- (cnt > current_msg + screen || cnt < current_msg - screen))
- cnt = current_msg; /* adjust if reads have passed screen bounds */
- else if (cnt >= msg_cnt || !argc || !*argv)
- /* adjust window to maintain position */
- cnt = (n_array[0] > msg_cnt) ? current_msg : n_array[0];
-
- oldscrn = screen;
- show_deleted = !!do_set(set_options, "show_deleted");
-
- /* Make sure we have at least $screen headers to print */
- if (cnt > 0 && !iscurses && first_char == 'h') {
- int top, bot = cnt;
- /* first count how many messages we can print without adjusting */
- for (pageful = 0; pageful<screen && bot<msg_cnt && bot; bot += srch)
- if (show_deleted || isoff(msg[bot].m_flags, DELETE))
- pageful++;
- /* if we can't print a pagefull of hdrs, back up till we can */
- for (top = cnt-srch; pageful<screen && top && top<msg_cnt; top -= srch)
- if (show_deleted || isoff(msg[top].m_flags, DELETE))
- pageful++;
- if (srch < 0)
- cnt = bot; /* the search was upside down */
- else
- cnt = top + (pageful == screen);
- pageful = 0; /* Used later as an index, so reset */
- } else if (cnt > 0 && srch < 0)
- cnt = max(cnt - screen, 0);
- else
- cnt = max(cnt, 0);
-
- for (;pageful<screen && cnt<msg_cnt && isoff(glob_flags, WAS_INTR); cnt++) {
- if (!iscurses && !show_deleted && first_char == 'h'
- && ison(msg[cnt].m_flags, DELETE))
- continue;
- n_array[pageful++] = cnt;
- /* this message was displayed -- set the bit */
- if (list)
- set_msg_bit(list, cnt);
- /* if do_pipe, don't output anything */
- if (ison(glob_flags, DO_PIPE))
- continue;
- p = compose_hdr(cnt);
- if (!istool && (!iscurses || ison(glob_flags, IS_GETTING)))
- puts(p);
- #ifdef SUNTOOL
- else if (istool) {
- if (cnt == current_msg) /* embolden or reverse-video */
- highlight(hdr_win, 0,pageful*l_height(), p);
- else
- (void) pw_text(hdr_win, 0, pageful * l_height(), PIX_SRC,
- mush_font, p);
- Clrtoeol(hdr_win, strlen(p)*l_width(), pageful*l_height());
- }
- #endif /* SUNTOOL */
-
- #ifdef CURSES
- else if (iscurses) {
- move(pageful, 0);
- printw("%-.*s", COLS-2, p), clrtoeol();
- }
- #endif /* CURSES */
- }
- /* just in case a signal stopped us */
- off_intr();
- pageful++;
- #ifdef CURSES
- if (iscurses && pageful < screen)
- move(pageful, 0), clrtobot();
- #endif /* CURSES */
- if (cnt == msg_cnt) {
- while (pageful <= screen) {
- n_array[pageful-1] = msg_cnt+1; /* assign out-of-range values */
- #ifdef SUNTOOL
- if (istool)
- Clrtoeol(hdr_win, 0, pageful * l_height());
- #endif /* SUNTOOL */
- ++pageful;
- }
- }
- #ifdef SUNTOOL
- if (istool) {
- Scrollbar sb = (Scrollbar) window_get(hdr_sw, WIN_VERTICAL_SCROLLBAR);
-
- if (show_deleted) {
- scrollbar_set(sb,
- SCROLL_OBJECT_LENGTH, msg_cnt,
- SCROLL_VIEW_START, n_array[0],
- 0);
- } else {
- int i, not_deleted, start;
-
- for (i = start = 0; i < n_array[0]; i++)
- if (!ison(msg[i].m_flags, DELETE))
- start++;
- for (not_deleted = start; i < msg_cnt; i++)
- if (!ison(msg[i].m_flags, DELETE))
- not_deleted++;
- scrollbar_set(sb,
- SCROLL_OBJECT_LENGTH, not_deleted,
- SCROLL_VIEW_START, start,
- 0);
- }
-
- scrollbar_paint(sb);
- mail_status(0);
- }
- #endif /* SUNTOOL */
-
- return 0;
- }
-
- #define NEW 1
- #define ALL 2
-
- specl_hdrs(argv, list)
- char **argv, list[];
- {
- u_long special = 0;
- int n = 0;
-
- while (argv[0][++n])
- switch(argv[0][n]) {
- case 'a': special = ALL;
- when 'n': special = NEW;
- when 'u': special = UNREAD;
- when 'o': special = OLD;
- when 'd': special = DELETE;
- when 'r': special = REPLIED;
- when 's': special = SAVED;
- when 'p': special = PRESERVE;
- otherwise: print("choose from n,u,o,d,r,s,p or a"); return -1;
- }
- if (debug)
- (void) check_flags(special);
-
- for (n = 0; n < msg_cnt; n++) {
- /*
- * First, see if we're looking for NEW messages.
- * If so, then check to see if the msg is unread and not old.
- * If special > ALL, then special has a mask of bits describing
- * the state of the message.
- */
- if (ison(glob_flags, IS_PIPE)&& !msg_bit(list, n))
- continue;
- if (special == ALL || special == NEW &&
- (ison(msg[n].m_flags, UNREAD) && isoff(msg[n].m_flags, OLD))) {
- if (isoff(glob_flags, DO_PIPE))
- print("%s\n", compose_hdr(n));
- if (list)
- set_msg_bit(list, n);
- } else if (special > ALL && ison(msg[n].m_flags, special)) {
- if (isoff(glob_flags, DO_PIPE))
- print("%s\n", compose_hdr(n));
- if (list)
- set_msg_bit(list, n);
- } else {
- if (list)
- unset_msg_bit(list, n);
- if (debug) {
- (void) printf("msg[%d].m_flags: %d", n, msg[n].m_flags);
- (void) check_flags(msg[n].m_flags);
- }
- }
- }
- return 0;
- }
-
- #define Strncpy(buf,p) (void)(strncpy(buf,p,sizeof(buf)),buf[sizeof(buf)-1]=0)
-
- /*
- * format a header from the information about a message (from, to, date,
- * subject, etc..). The header for message number "cnt" is built and is
- * returned in the static buffer "buf". There will be *at least* 9 chars
- * in the buffer which will be something like: " 123 >N " The breakdown
- * is as follows: 4 chars for the message number, 1 space, 1 char for '>'
- * (if current message) and two spaces for message status (new, unread, etc)
- * followed by 1 terminating space.
- * Read other comments in the routine for more info.
- */
- char *
- format_hdr(cnt, hdr_fmt, show_to)
- int cnt, show_to;
- char *hdr_fmt;
- {
- static char buf[256];
- register char *p, *p2, *b;
- int len, do_pad = FALSE, val, pad, got_dot, isauthor = 0, n;
- char from[HDRSIZ], subject[256], date[64], lines[16];
- char to[256], addr[256], name[256], status[4];
- char Day[3], Mon[4], Tm[8], Yr[5], Wkday[4], Zone[8], *date_p;
-
- /* status of the message */
- if (ison(msg[cnt].m_flags, DELETE))
- status[0] = '*';
- else if (ison(msg[cnt].m_flags, PRESERVE))
- status[0] = 'P';
- else if (ison(msg[cnt].m_flags, SAVED))
- status[0] = 'S';
- else if (ison(msg[cnt].m_flags, OLD) && ison(msg[cnt].m_flags, UNREAD))
- status[0] = 'U';
- else if (ison(msg[cnt].m_flags, PRINTED))
- status[0] = 'p';
- else if (ison(msg[cnt].m_flags, FORWARD))
- status[0] = 'f';
- else if (isoff(msg[cnt].m_flags, UNREAD))
- status[0] = ' ';
- else
- status[0] = 'N';
-
- if (ison(msg[cnt].m_flags, REPLIED))
- status[1] = 'r';
- else
- status[1] = ' ';
-
- to[0] = from[0] = subject[0] = date[0] = lines[0] = addr[0] =
- name[0] = Day[0] = Mon[0] = Tm[0] = Yr[0] = Wkday[0] = 0;
-
- /* who's the message to */
- if ((p = header_field(cnt, "resent-to")) ||
- (p = header_field(cnt, "to")) ||
- (p = header_field(cnt, "apparently-to")))
- Strncpy(to, p);
-
- /* who's the message from */
- if ((p = header_field(cnt, "from")) && strcpy(from, p)
- || (p = reply_to(cnt, 0, from))) {
- /* NOTE: this fails if the sender has '<' or '!' in
- * the RFC822 comment fields -- leading "comment"
- * or trailing (comment) -- but that isn't critical
- */
- if ((p2 = rindex(p, '!')) || (p2 = index(p, '<')))
- p = p2 + 1;
- } else
- p = strcpy(from, "unknown"); /* just in case */
- /* If the From field contains the user's login name, then the message
- * could be from the user -- attempt to give more useful information
- * by telling to whom the message was sent. This is not possible if
- * the "to" header failed to get info (which is probably impossible).
- * Use take_me_off() to be sure the message really is from the current
- * user and not just someone with the same login at another site.
- */
- if (show_to && !strncmp(p, login, strlen(login)))
- (void) take_me_off(from);
- if (show_to && (isauthor = !*from)) { /* assign and test */
- (void) get_name_n_addr(to, name+4, addr+4);
- if (addr[4])
- (void) strncpy(addr, "TO: ", 4);
- if (name[4]) { /* check to see if a name got added */
- (void) strncpy(name, "TO: ", 4);
- Strncpy(from, name);
- } else
- Strncpy(from, addr);
- } else
- (void) get_name_n_addr(from, name, addr);
-
- if (ison(glob_flags, DATE_RECV))
- date_p = msg[cnt].m_date_recv;
- else
- date_p = msg[cnt].m_date_sent;
- (void) date_to_string(date_p, Yr, Mon, Day, Wkday, Tm, Zone, date);
-
- /* and the subject */
- if (p = header_field(cnt, "subject"))
- Strncpy(subject, p);
-
- /* now, construct a header out of a format string */
- if (!hdr_fmt)
- hdr_fmt = hdr_format;
-
- (void) sprintf(buf, "%4.d ", cnt+1);
- b = buf+5;
- *b++ = ((cnt == current_msg && !iscurses)? '>': ' ');
- *b++ = status[0], *b++ = status[1];
- *b++ = ' ';
- /* Count chars since beginning of buf. Initialize to 9 (strlen(buf) so far)
- * This magic number is used in other places in msgs.c and mail.c
- */
- n = 9;
- for (p = hdr_fmt; *p; p++)
- if (*p == '\\')
- switch (*++p) {
- case 't':
- while (n % 8)
- n++, *b++ = ' ';
- when 'n':
- n = 1, *b++ = '\n';
- otherwise: n++, *b++ = *p;
- }
- else if (*p == '%') {
- char fmt[64];
-
- p2 = fmt;
- /* first check for string padding: %5n, %.4a, %10.5f, %-.3l etc. */
- do_pad = pad = val = got_dot = 0;
- *p2++ = '%';
- if (p[1] != '-')
- *p2++ = '-';
- else
- ++p;
- while (isdigit(*++p) || !got_dot && *p == '.') {
- if (*p == '.')
- got_dot = TRUE, val = pad, pad = 0;
- else
- pad = pad * 10 + *p - '0';
- *p2++ = *p;
- }
- if (!got_dot && isdigit(p[-1])) {
- *p2 = 0; /* assure null termination */
- val = atoi(fmt+1);
- if (val < 0)
- val = -val;
- p2 += strlen(sprintf(p2, ".%d", val));
- }
- pad = min(pad, val);
- *p2++ = 's', *p2 = 0;
- if (!*p)
- break;
- switch (*p) {
- case 'f': p2 = from, do_pad = TRUE;
- when 'a':
- if (!*(p2 = addr))
- p2 = from;
- do_pad = TRUE;
- when 'n':
- if (!*(p2 = name))
- p2 = from, do_pad = TRUE;
- when '%': p2 = "%";
- when 't': p2 = to;
- when 's': p2 = subject;
- when 'l': p2 = sprintf(lines, "%d", msg[cnt].m_lines);
- when 'c': p2 = sprintf(lines, "%ld", msg[cnt].m_size);
- when 'i': (p2 = header_field(cnt, "message-id")) || (p2 = "");
- /* date formatting chars */
- when 'd': p2 = date; /* the full date */
- when 'T': p2 = Tm;
- when 'M': p2 = Mon;
- when 'Y': p2 = Yr;
- when 'y': p2 = Yr+2;
- when 'N': p2 = Day;
- when 'D': case 'W': p2 = Wkday;
- when 'Z': p2 = Zone;
- /* Any selected header */
- when '?': {
- p2 = p + 1;
- p = index(p2, '?');
- if (p) {
- *p = 0;
- if (!(p2 = header_field(cnt, p2)))
- p2 = "";
- *p = '?';
- } else {
- p = p2 + (strlen(p2) - 1);
- if (!(p2 = header_field(cnt, p2)))
- p2 = "";
- }
- }
- otherwise: continue; /* unknown formatting char */
- }
- if (do_pad && pad && strlen(p2) > pad) {
- char *old_p2 = p2, *p3;
- /* if addr is too long, move pointer forward till the
- * "important" part is readable only for ! paths/addresses.
- */
- while (p3 = index(p2, '!')) {
- int tmp = strlen(p3+1); /* xenix has compiler problems */
- p2 = p3+1;
- if (tmp + isauthor*4 < pad) {
- if (isauthor && (p2 -= 4) < old_p2)
- p2 = old_p2;
- break;
- }
- }
- if (isauthor && p2 > old_p2+4 && !p3 && strlen(p2) + 4 > pad)
- p2 -= 4;
- if (old_p2 != p2 && isauthor)
- (void) strncpy(p2, "TO: ", 4); /* doesn't null terminate */
- }
- len = strlen(sprintf(b, fmt, p2));
- n += len, b += len;
- /* Get around a bug in 5.5 IBM RT which pads with NULs not ' ' */
- while (n && !*(b-1))
- b--, n--;
- } else
- n++, *b++ = *p;
- for (*b-- = 0; isspace(*b) && *b != '\n'; --b)
- *b = 0;
- return buf;
- }
-
- char *
- compose_hdr(cnt)
- int cnt;
- {
- if (!hdr_format)
- hdr_format = DEF_HDR_FMT;
- return format_hdr(cnt, hdr_format, TRUE);
- }
-
- /*
- * Using message "n", build a list of recipients that you would mail to if
- * you were to reply to this message. If "all" is true, then it will take
- * everyone from the To line in addition to the original sender.
- * route_addresses() is called from mail.c, not from here. There are too many
- * other uses for reply_to to always require reconstruction of return paths.
- * Note that we do NOT deal with Cc paths here either.
- * Check to make sure that we in fact return a legit address (i.e. not blanks
- * or null). If such a case occurs, return login name. Always pad end w/blank.
- */
- char *
- reply_to(n, all, buf)
- char buf[];
- {
- register char *p = NULL, *p2, *b = buf, *field;
- char line[256], name[256], addr[256], *unscramble_addr();
-
- if (field = do_set(set_options, "reply_to_hdr")) {
- #ifndef MSG_SEPARATOR
- if (!*field)
- goto DoFrom; /* special case -- get the colon-less From line */
- #endif /* MSG_SEPARATOR */
- field = lcase_strcpy(line, field);
- while (*field) {
- if (p2 = any(field, " \t,:"))
- *p2 = 0;
- #ifndef MSG_SEPARATOR
- if (!lcase_strncmp(field, "from_", -1))
- goto DoFrom;
- #endif /* MSG_SEPARATOR */
- if ((p = header_field(n, field)) || !p2)
- break;
- else {
- field = p2+1;
- while (isspace(*field) || *field == ':' || *field == ',')
- field++;
- }
- }
- if (!p)
- print("Warning: message contains no `reply_to_hdr' headers.\n");
- }
- if (p || (!p && ((p = header_field(n, field = "reply-to")) ||
- (p = header_field(n, field = "from")) ||
- (p = header_field(n, field = "return-path")))))
- skipspaces(0);
- else if (!p) {
- #ifndef MSG_SEPARATOR
- DoFrom:
- field = "from_";
- /* if all else fails, then get the first token in "From" line */
- if (p2 = msg_get(n, line, sizeof line))
- p = index(p2, ' ');
- else
- return "";
- skipspaces(1);
- if (p2 = index(p, ' '))
- *p2 = 0;
- (void) unscramble_addr(p, line); /* p is safely recopied to line */
- p = line;
- #else /* MSG_SEPARATOR */
- wprint("Warning: unable to find who msg %d is from!\n", n+1);
- #endif /* MSG_SEPARATOR */
- }
- (void) get_name_n_addr(p, name, addr);
- if (!name[0] && (!lcase_strncmp(field, "return-path", -1) ||
- !lcase_strncmp(field, "from_", -1))) {
- /*
- * Get the name of the author of the message we're replying to from the
- * From: header since that header contains the author's name. Only do
- * this if the address was gotten from the return-path or from_ lines
- * because this is the only way to guarantee that the return address
- * matches the author's name. Reply-To: may not be the same person!
- * Check Resent-From: if the address came from the from_ line, else
- * check From:, and finally Sender: or Name:.
- */
- if (!lcase_strncmp(field, "from_", -1) &&
- (p = header_field(n, "resent-from")) ||
- (p = header_field(n, "from")) ||
- (p = header_field(n, "sender")))
- (void) get_name_n_addr(p, name, NULL);
- if (!name[0] && (p = header_field(n, "name")))
- (void) strcpy(name, p);
- if (name[0]) {
- if ((p = any(name, "(<,\"")) && (*p == ',' || *p == '<'))
- *b++ = '"';
- b += Strcpy(b, name);
- if (p && (*p == ',' || *p == '<'))
- *b++ = '"';
- *b++ = ' ', *b++ = '<';
- }
- b += Strcpy(b, addr);
- if (name[0])
- *b++ = '>', *b = 0;
- } else
- b += Strcpy(buf, p);
-
- /*
- * if `all' is true, append everyone on the "To:" line(s).
- * cc_to(), called separately, will catch the cc's
- */
- if (all) {
- int lim = HDRSIZ - (b - buf) - 2;
- /* Check for overflow on each copy.
- * The assumption that HDRSIZ is correct is unwise, but I know it
- * to be true for Mush. Be forewarned if you call this routine.
- */
- if (lim > 0 && (p = header_field(n, "resent-to")) && *p) {
- *b++ = ',', *b++ = ' ';
- p[lim] = '\0'; /* prevent overflow */
- b += Strcpy(b, p);
- lim = HDRSIZ - (b - buf) - 2;
- }
- if (lim > 0 && (p = header_field(n, "to")) && *p) {
- *b++ = ',', *b++ = ' ';
- p[lim] = '\0'; /* prevent overflow */
- b += Strcpy(b, p);
- lim = HDRSIZ - (b - buf) - 2;
- }
- if (lim > 0 && (p = header_field(n, "apparently-to")) && *p) {
- *b++ = ',', *b++ = ' ';
- p[lim] = '\0'; /* prevent overflow */
- b += Strcpy(b, p);
- lim = HDRSIZ - (b - buf) - 2;
- }
- /* Also append the Resent-From address if there is one. */
- if (lim > 0 && (p = header_field(n, "resent-from")) && *p) {
- *b++ = ',', *b++ = ' ';
- p[lim] = '\0'; /* prevent overflow */
- (void) strcpy(b, p);
- }
- }
- fix_up_addr(buf);
- /* p2 used to save boolean value of $metoo */
- if (!(p2 = do_set(set_options, "metoo"))) {
- /* Save the original name/addr in case it is the only one */
- (void) get_name_n_addr(buf, name, addr);
- take_me_off(buf);
- }
- for (p = buf; *p == ',' || isspace(*p); p++)
- ;
- if (!*p)
- if (p2) /* take_me_off() was not done */
- (void) strcpy(buf, login);
- else
- (void) sprintf(buf, "%s <%s>", name, addr);
- return buf;
- }
-
- char *
- subject_to(n, buf)
- register char *buf;
- {
- register char *p;
- buf[0] = 0; /* make sure it's already null terminated */
- if (!(p = header_field(n, "subject")))
- return NULL;
- if (lcase_strncmp(p, "Re:", 3))
- (void) strcpy(buf, "Re: ");
- return strcat(buf, p);
- }
-
- char *
- cc_to(n, buf)
- register char *buf;
- {
- register char *p;
- buf[0] = 0; /* make sure it's already null terminated */
- if (!(p = header_field(n, "cc")))
- return NULL;
- fix_up_addr(p);
- if (!do_set(set_options, "metoo"))
- take_me_off(p);
- return strcpy(buf, p);
- }
-