📄 list.c
字号:
/* * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)list.c 8.2 (Berkeley) 4/19/94";#endif /* not lint */#include "rcv.h"#include <ctype.h>#include "extern.h"/* * Mail -- a mail program * * Message list handling. *//* * Convert the user string of message numbers and * store the numbers into vector. * * Returns the count of messages picked up or -1 on error. */intgetmsglist(buf, vector, flags) char *buf; int *vector, flags;{ register int *ip; register struct message *mp; if (msgCount == 0) { *vector = 0; return 0; } if (markall(buf, flags) < 0) return(-1); ip = vector; for (mp = &message[0]; mp < &message[msgCount]; mp++) if (mp->m_flag & MMARK) *ip++ = mp - &message[0] + 1; *ip = 0; return(ip - vector);}/* * Mark all messages that the user wanted from the command * line in the message structure. Return 0 on success, -1 * 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;intmarkall(buf, f) char buf[]; int f;{ register char **np; register int i; register struct message *mp; char *namelist[NMLSIZE], *bufp; 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; mc = 0; np = &namelist[0]; scaninit(); tok = scan(&bufp); star = 0; other = 0; beg = 0; while (tok != TEOL) { switch (tok) { case TNUMBER:number: if (star) { printf("No numbers mixed with *\n"); return(-1); } mc++; other++; if (beg != 0) { if (check(lexnumber, f)) return(-1); for (i = beg; i <= lexnumber; i++) if (f == MDELETED || (message[i - 1].m_flag & MDELETED) == 0) mark(i); beg = 0; break; } beg = lexnumber; if (check(beg, f)) return(-1); tok = scan(&bufp); regret(tok); if (tok != TDASH) { mark(beg); beg = 0; } break; case TPLUS: if (beg != 0) { printf("Non-numeric second argument\n"); return(-1); } i = valdot; do { i++; if (i > msgCount) { printf("Referencing beyond EOF\n"); return(-1); } } while ((message[i - 1].m_flag & MDELETED) != f); mark(i); break; case TDASH: if (beg == 0) { i = valdot; do { i--; if (i <= 0) { printf("Referencing before 1\n"); return(-1); } } while ((message[i - 1].m_flag & MDELETED) != f); mark(i); } break; case TSTRING: if (beg != 0) { printf("Non-numeric second argument\n"); return(-1); } other++; 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: case TUP: case TDOT: lexnumber = metamess(lexstring[0], f); if (lexnumber == -1) return(-1); goto number; case TSTAR: if (other) { printf("Can't mix \"*\" with anything\n"); return(-1); } star++; break; case TERROR: return -1; } tok = scan(&bufp); } lastcolmod = colmod; *np = NOSTR; mc = 0; if (star) { for (i = 0; i < msgCount; i++) if ((message[i].m_flag & MDELETED) == f) { mark(i+1); mc++; } if (mc == 0) { printf("No applicable messages.\n"); return(-1); } return(0); } /* * If no numbers were given, mark all of the messages, * so that we can unmark any whose sender was not selected * if any user names were given. */ if ((np > namelist || colmod != 0) && mc == 0) for (i = 1; i <= msgCount; i++) if ((message[i-1].m_flag & MDELETED) == f) mark(i); /* * If any names were given, go through and eliminate any * messages whose senders were not requested. */ if (np > namelist) { for (i = 1; i <= msgCount; i++) { for (mc = 0, np = &namelist[0]; *np != NOSTR; np++) if (**np == '/') { if (matchsubj(*np, i)) { mc++; break; } } else { if (matchsender(*np, i)) { mc++; break; } } if (mc == 0) unmark(i); } /* * Make sure we got some decent messages. */ mc = 0; for (i = 1; i <= msgCount; i++) if (message[i-1].m_flag & MMARK) { mc++; break; } if (mc == 0) { printf("No applicable messages from {%s", namelist[0]); for (np = &namelist[1]; *np != NOSTR; np++) printf(", %s", *np); printf("}\n"); 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. */intevalcol(col) int 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);}/* * Check the passed message number for legality and proper flags. * If f is MDELETED, then either kind will do. Otherwise, the message * has to be undeleted. */intcheck(mesg, f) int mesg, f;{ register struct message *mp; if (mesg < 1 || mesg > msgCount) { printf("%d: Invalid message number\n", mesg); return(-1); } mp = &message[mesg-1]; if (f != MDELETED && (mp->m_flag & MDELETED) != 0) { printf("%d: Inappropriate message\n", mesg); return(-1); } return(0);}/* * Scan out the list of string arguments, shell style * for a RAWLIST. */intgetrawlist(line, argv, argc) char line[]; char **argv; int argc;{ register char c, *cp, *cp2, quotec; int argn; char linebuf[BUFSIZ]; argn = 0; cp = line; for (;;) { for (; *cp == ' ' || *cp == '\t'; cp++) ; if (*cp == '\0')
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -