X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/f7a4f91c2dbb1507d58980eec2fa4c714381d545..3b645f6538d12d3b5ef8a9c3329366444d52a7d8:/usr/src/usr.bin/mail/list.c diff --git a/usr/src/usr.bin/mail/list.c b/usr/src/usr.bin/mail/list.c index 10abf7f6ac..31892e1cdd 100644 --- a/usr/src/usr.bin/mail/list.c +++ b/usr/src/usr.bin/mail/list.c @@ -9,7 +9,7 @@ * Message list handling. */ -static char *SccsId = "@(#)list.c 1.2 %G%"; +static char *SccsId = "@(#)list.c 2.2 %G%"; /* * Convert the user string of message numbers and @@ -41,15 +41,48 @@ getmsglist(buf, vector, flags) * on error. */ +/* + * Bit values for colon modifiers. + */ + +#define CMNEW 01 /* New messages */ +#define CMOLD 02 /* Old messages */ +#define CMUNREAD 04 /* Unread messages */ +#define CMDELETED 010 /* Deleted messages */ +#define CMREAD 020 /* Read messages */ + +/* + * The following table describes the letters which can follow + * the colon and gives the corresponding modifier bit. + */ + +struct coltab { + char co_char; /* What to find past : */ + int co_bit; /* Associated modifier bit */ + int co_mask; /* m_status bits to mask */ + int co_equal; /* ... must equal this */ +} coltab[] = { + 'n', CMNEW, MNEW, MNEW, + 'o', CMOLD, MNEW, 0, + 'u', CMUNREAD, MREAD, 0, + 'd', CMDELETED, MDELETED, MDELETED, + 'r', CMREAD, MREAD, MREAD, + 0, 0, 0, 0 +}; + +static int lastcolmod; + markall(buf, f) char buf[]; { register char **np; register int i; + register struct message *mp; char *namelist[NMLSIZE], *bufp; - int tok, beg, mc, star, other, valdot; + int tok, beg, mc, star, other, valdot, colmod, colresult; valdot = dot - &message[0] + 1; + colmod = 0; for (i = 1; i <= msgCount; i++) unmark(i); bufp = buf; @@ -74,7 +107,8 @@ number: if (check(lexnumber, f)) return(-1); for (i = beg; i <= lexnumber; i++) - mark(i); + if ((message[i - 1].m_flag & MDELETED) == f) + mark(i); beg = 0; break; } @@ -119,7 +153,17 @@ number: return(-1); } other++; - *np++ = savestr(lexstring); + if (lexstring[0] == ':') { + colresult = evalcol(lexstring[1]); + if (colresult == 0) { + printf("Unknown colon modifier \"%s\"\n", + lexstring); + return(-1); + } + colmod |= colresult; + } + else + *np++ = savestr(lexstring); break; case TDOLLAR: @@ -140,6 +184,7 @@ number: } tok = scan(&bufp); } + lastcolmod = colmod; *np = NOSTR; mc = 0; if (star) { @@ -161,7 +206,7 @@ number: * if any user names were given. */ - if (np > namelist && mc == 0) + if ((np > namelist || colmod != 0) && mc == 0) for (i = 1; i <= msgCount; i++) if ((message[i-1].m_flag & (MSAVED|MDELETED)) == f) mark(i); @@ -209,6 +254,54 @@ number: return(-1); } } + + /* + * If any colon modifiers were given, go through and + * unmark any messages which do not satisfy the modifiers. + */ + + if (colmod != 0) { + for (i = 1; i <= msgCount; i++) { + register struct coltab *colp; + + mp = &message[i - 1]; + for (colp = &coltab[0]; colp->co_char; colp++) + if (colp->co_bit & colmod) + if ((mp->m_flag & colp->co_mask) + != colp->co_equal) + unmark(i); + + } + for (mp = &message[0]; mp < &message[msgCount]; mp++) + if (mp->m_flag & MMARK) + break; + if (mp >= &message[msgCount]) { + register struct coltab *colp; + + printf("No messages satisfy"); + for (colp = &coltab[0]; colp->co_char; colp++) + if (colp->co_bit & colmod) + printf(" :%c", colp->co_char); + printf("\n"); + return(-1); + } + } + return(0); +} + +/* + * Turn the character after a colon modifier into a bit + * value. + */ +evalcol(col) +{ + register struct coltab *colp; + + if (col == 0) + return(lastcolmod); + for (colp = &coltab[0]; colp->co_char; colp++) + if (colp->co_char == col) + return(colp->co_bit); return(0); } @@ -449,7 +542,7 @@ sender(str, mesg) register char *cp; mp = &message[mesg-1]; - cp = nameof(mp); + cp = nameof(mp, 0); return(icequal(cp, str)); } @@ -467,7 +560,7 @@ matchsubj(str, mesg) char *str; { register struct message *mp; - register char *cp, *cp2; + register char *cp, *cp2, *backup; str++; if (strlen(str) == 0) @@ -484,11 +577,14 @@ matchsubj(str, mesg) cp2 = hfield("subject", mp); if (cp2 == NOSTR) return(0); + backup = cp2; while (*cp2) { if (*cp == 0) return(1); - if (raise(*cp++) != raise(*cp2++)) + if (raise(*cp++) != raise(*cp2++)) { + cp2 = ++backup; cp = str; + } } return(*cp == 0); }