# 2.11BSD#431 - /usr/src/ucb/Mail/list.c

##### Functions

    check             X
    evalcol           X
    first             X
    getmsglist        X
    getrawlist        X
    mark              X
    markall           X
    matchsender       X
    matchsubj         X
    metamess          X
    regret            X
    scan              X
    scaninit          X
    unmark            X

##### Variables

    coltab            X
    lastscan          X
    singles           X

##### Macros

    CMDELETED         X
    CMNEW             X
    CMOLD             X
    CMREAD            X
    CMUNREAD          X

##### struct's

    coltab            X
    lex               X

       1: /*
       2:  * Copyright (c) 1980 Regents of the University of California.
       3:  * All rights reserved.
       4:  *
       5:  * Redistribution and use in source and binary forms, with or without
       6:  * modification, are permitted provided that the following conditions
       7:  * are met:
       8:  * 1. Redistributions of source code must retain the above copyright
       9:  *    notice, this list of conditions and the following disclaimer.
      10:  * 2. Redistributions in binary form must reproduce the above copyright
      11:  *    notice, this list of conditions and the following disclaimer in the
      12:  *    documentation and/or other materials provided with the distribution.
      13:  * 3. All advertising materials mentioning features or use of this software
      14:  *    must display the following acknowledgement:
      15:  *	This product includes software developed by the University of
      16:  *	California, Berkeley and its contributors.
      17:  * 4. Neither the name of the University nor the names of its contributors
      18:  *    may be used to endorse or promote products derived from this software
      19:  *    without specific prior written permission.
      20:  *
      21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31:  * SUCH DAMAGE.
      32:  */
      33:
      34: #if !defined(lint) && defined(DOSCCS)
      35: static char sccsid[] = "@(#)list.c	5.14 (Berkeley) 6/1/90";
      36: #endif
      37:
      38: #include "rcv.h"
      39: #include <ctype.h>
      40:
      41: /*
      42:  * Mail -- a mail program
      43:  *
      44:  * Message list handling.
      45:  */
      46:
      47: /*
      48:  * Convert the user string of message numbers and
      49:  * store the numbers into vector.
      50:  *
      51:  * Returns the count of messages picked up or -1 on error.
      52:  */
      53:
      54: getmsglist(buf, vector, flags)
      55:     char *buf;
      56:     int *vector;
      57: {
      58:     register int *ip;
      59:     register struct message *mp;
      60:
      61:     if (msgCount == 0) {
      62:         *vector = 0;
      63:         return 0;
      64:     }
      65:     if (markall(buf, flags) < 0)
      66:         return(-1);
      67:     ip = vector;
      68:     for (mp = &message[0]; mp < &message[msgCount]; mp++)
      69:         if (mp->m_flag & MMARK)
      70:             *ip++ = mp - &message[0] + 1;
      71:     *ip = 0;
      72:     return(ip - vector);
      73: }
      74:
      75: /*
      76:  * Mark all messages that the user wanted from the command
      77:  * line in the message structure.  Return 0 on success, -1
      78:  * on error.
      79:  */
      80:
      81: /*
      82:  * Bit values for colon modifiers.
      83:  */
      84:
      85: #define CMNEW       01      /* New messages */
      86: #define CMOLD       02      /* Old messages */
      87: #define CMUNREAD    04      /* Unread messages */
      88: #define CMDELETED   010     /* Deleted messages */
      89: #define CMREAD      020     /* Read messages */
      90:
      91: /*
      92:  * The following table describes the letters which can follow
      93:  * the colon and gives the corresponding modifier bit.
      94:  */
      95:
      96: struct coltab {
      97:     char    co_char;        /* What to find past : */
      98:     int co_bit;         /* Associated modifier bit */
      99:     int co_mask;        /* m_status bits to mask */
     100:     int co_equal;       /* ... must equal this */
     101: } coltab[] = {
     102:     'n',        CMNEW,      MNEW,       MNEW,
     103:     'o',        CMOLD,      MNEW,       0,
     104:     'u',        CMUNREAD,   MREAD,      0,
     105:     'd',        CMDELETED,  MDELETED,   MDELETED,
     106:     'r',        CMREAD,     MREAD,      MREAD,
     107:     0,      0,      0,      0
     108: };
     109:
     110: static  int lastcolmod;
     111:
     112: markall(buf, f)
     113:     char buf[];
     114: {
     115:     register char **np;
     116:     register int i;
     117:     register struct message *mp;
     118:     char *namelist[NMLSIZE], *bufp;
     119:     int tok, beg, mc, star, other, valdot, colmod, colresult;
     120:
     121:     valdot = dot - &message[0] + 1;
     122:     colmod = 0;
     123:     for (i = 1; i <= msgCount; i++)
     124:         unmark(i);
     125:     bufp = buf;
     126:     mc = 0;
     127:     np = &namelist[0];
     128:     scaninit();
     129:     tok = scan(&bufp);
     130:     star = 0;
     131:     other = 0;
     132:     beg = 0;
     133:     while (tok != TEOL) {
     134:         switch (tok) {
     135:         case TNUMBER:
     136: number:
     137:             if (star) {
     138:                 printf("No numbers mixed with *\n");
     139:                 return(-1);
     140:             }
     141:             mc++;
     142:             other++;
     143:             if (beg != 0) {
     144:                 if (check(lexnumber, f))
     145:                     return(-1);
     146:                 for (i = beg; i <= lexnumber; i++)
     147:                     if (f == MDELETED || (message[i - 1].m_flag & MDELETED) == 0)
     148:                         mark(i);
     149:                 beg = 0;
     150:                 break;
     151:             }
     152:             beg = lexnumber;
     153:             if (check(beg, f))
     154:                 return(-1);
     155:             tok = scan(&bufp);
     156:             regret(tok);
     157:             if (tok != TDASH) {
     158:                 mark(beg);
     159:                 beg = 0;
     160:             }
     161:             break;
     162:
     163:         case TPLUS:
     164:             if (beg != 0) {
     165:                 printf("Non-numeric second argument\n");
     166:                 return(-1);
     167:             }
     168:             i = valdot;
     169:             do {
     170:                 i++;
     171:                 if (i > msgCount) {
     172:                     printf("Referencing beyond EOF\n");
     173:                     return(-1);
     174:                 }
     175:             } while ((message[i - 1].m_flag & MDELETED) != f);
     176:             mark(i);
     177:             break;
     178:
     179:         case TDASH:
     180:             if (beg == 0) {
     181:                 i = valdot;
     182:                 do {
     183:                     i--;
     184:                     if (i <= 0) {
     185:                         printf("Referencing before 1\n");
     186:                         return(-1);
     187:                     }
     188:                 } while ((message[i - 1].m_flag & MDELETED) != f);
     189:                 mark(i);
     190:             }
     191:             break;
     192:
     193:         case TSTRING:
     194:             if (beg != 0) {
     195:                 printf("Non-numeric second argument\n");
     196:                 return(-1);
     197:             }
     198:             other++;
     199:             if (lexstring[0] == ':') {
     200:                 colresult = evalcol(lexstring[1]);
     201:                 if (colresult == 0) {
     202:                     printf("Unknown colon modifier \"%s\"\n",
     203:                         lexstring);
     204:                     return(-1);
     205:                 }
     206:                 colmod |= colresult;
     207:             }
     208:             else
     209:                 *np++ = savestr(lexstring);
     210:             break;
     211:
     212:         case TDOLLAR:
     213:         case TUP:
     214:         case TDOT:
     215:             lexnumber = metamess(lexstring[0], f);
     216:             if (lexnumber == -1)
     217:                 return(-1);
     218:             goto number;
     219:
     220:         case TSTAR:
     221:             if (other) {
     222:                 printf("Can't mix \"*\" with anything\n");
     223:                 return(-1);
     224:             }
     225:             star++;
     226:             break;
     227:
     228:         case TERROR:
     229:             return -1;
     230:         }
     231:         tok = scan(&bufp);
     232:     }
     233:     lastcolmod = colmod;
     234:     *np = NOSTR;
     235:     mc = 0;
     236:     if (star) {
     237:         for (i = 0; i < msgCount; i++)
     238:             if ((message[i].m_flag & MDELETED) == f) {
     239:                 mark(i+1);
     240:                 mc++;
     241:             }
     242:         if (mc == 0) {
     243:             printf("No applicable messages.\n");
     244:             return(-1);
     245:         }
     246:         return(0);
     247:     }
     248:
     249:     /*
     250: 	 * If no numbers were given, mark all of the messages,
     251: 	 * so that we can unmark any whose sender was not selected
     252: 	 * if any user names were given.
     253: 	 */
     254:
     255:     if ((np > namelist || colmod != 0) && mc == 0)
     256:         for (i = 1; i <= msgCount; i++)
     257:             if ((message[i-1].m_flag & MDELETED) == f)
     258:                 mark(i);
     259:
     260:     /*
     261: 	 * If any names were given, go through and eliminate any
     262: 	 * messages whose senders were not requested.
     263: 	 */
     264:
     265:     if (np > namelist) {
     266:         for (i = 1; i <= msgCount; i++) {
     267:             for (mc = 0, np = &namelist[0]; *np != NOSTR; np++)
     268:                 if (**np == '/') {
     269:                     if (matchsubj(*np, i)) {
     270:                         mc++;
     271:                         break;
     272:                     }
     273:                 }
     274:                 else {
     275:                     if (matchsender(*np, i)) {
     276:                         mc++;
     277:                         break;
     278:                     }
     279:                 }
     280:             if (mc == 0)
     281:                 unmark(i);
     282:         }
     283:
     284:         /*
     285: 		 * Make sure we got some decent messages.
     286: 		 */
     287:
     288:         mc = 0;
     289:         for (i = 1; i <= msgCount; i++)
     290:             if (message[i-1].m_flag & MMARK) {
     291:                 mc++;
     292:                 break;
     293:             }
     294:         if (mc == 0) {
     295:             printf("No applicable messages from {%s",
     296:                 namelist[0]);
     297:             for (np = &namelist[1]; *np != NOSTR; np++)
     298:                 printf(", %s", *np);
     299:             printf("}\n");
     300:             return(-1);
     301:         }
     302:     }
     303:
     304:     /*
     305: 	 * If any colon modifiers were given, go through and
     306: 	 * unmark any messages which do not satisfy the modifiers.
     307: 	 */
     308:
     309:     if (colmod != 0) {
     310:         for (i = 1; i <= msgCount; i++) {
     311:             register struct coltab *colp;
     312:
     313:             mp = &message[i - 1];
     314:             for (colp = &coltab[0]; colp->co_char; colp++)
     315:                 if (colp->co_bit & colmod)
     316:                     if ((mp->m_flag & colp->co_mask)
     317:                         != colp->co_equal)
     318:                         unmark(i);
     319:
     320:         }
     321:         for (mp = &message[0]; mp < &message[msgCount]; mp++)
     322:             if (mp->m_flag & MMARK)
     323:                 break;
     324:         if (mp >= &message[msgCount]) {
     325:             register struct coltab *colp;
     326:
     327:             printf("No messages satisfy");
     328:             for (colp = &coltab[0]; colp->co_char; colp++)
     329:                 if (colp->co_bit & colmod)
     330:                     printf(" :%c", colp->co_char);
     331:             printf("\n");
     332:             return(-1);
     333:         }
     334:     }
     335:     return(0);
     336: }
     337:
     338: /*
     339:  * Turn the character after a colon modifier into a bit
     340:  * value.
     341:  */
     342: evalcol(col)
     343: {
     344:     register struct coltab *colp;
     345:
     346:     if (col == 0)
     347:         return(lastcolmod);
     348:     for (colp = &coltab[0]; colp->co_char; colp++)
     349:         if (colp->co_char == col)
     350:             return(colp->co_bit);
     351:     return(0);
     352: }
     353:
     354: /*
     355:  * Check the passed message number for legality and proper flags.
     356:  * If f is MDELETED, then either kind will do.  Otherwise, the message
     357:  * has to be undeleted.
     358:  */
     359: check(mesg, f)
     360: {
     361:     register struct message *mp;
     362:
     363:     if (mesg < 1 || mesg > msgCount) {
     364:         printf("%d: Invalid message number\n", mesg);
     365:         return(-1);
     366:     }
     367:     mp = &message[mesg-1];
     368:     if (f != MDELETED && (mp->m_flag & MDELETED) != 0) {
     369:         printf("%d: Inappropriate message\n", mesg);
     370:         return(-1);
     371:     }
     372:     return(0);
     373: }
     374:
     375: /*
     376:  * Scan out the list of string arguments, shell style
     377:  * for a RAWLIST.
     378:  */
     379:
     380: getrawlist(line, argv, argc)
     381:     char line[];
     382:     char **argv;
     383:     int  argc;
     384: {
     385:     register char c, *cp, *cp2, quotec;
     386:     int argn;
     387:     char linebuf[BUFSIZ];
     388:
     389:     argn = 0;
     390:     cp = line;
     391:     for (;;) {
     392:         for (; *cp == ' ' || *cp == '\t'; cp++)
     393:             ;
     394:         if (*cp == '\0')
     395:             break;
     396:         if (argn >= argc - 1) {
     397:             printf(
     398:             "Too many elements in the list; excess discarded.\n");
     399:             break;
     400:         }
     401:         cp2 = linebuf;
     402:         quotec = '\0';
     403:         while ((c = *cp) != '\0') {
     404:             cp++;
     405:             if (quotec != '\0') {
     406:                 if (c == quotec)
     407:                     quotec = '\0';
     408:                 else if (c == '\\')
     409:                     switch (c = *cp++) {
     410:                     case '\0':
     411:                         *cp2++ = *--cp;
     412:                         break;
     413:                     case '0': case '1': case '2': case '3':
     414:                     case '4': case '5': case '6': case '7':
     415:                         c -= '0';
     416:                         if (*cp >= '0' && *cp <= '7')
     417:                             c = c * 8 + *cp++ - '0';
     418:                         if (*cp >= '0' && *cp <= '7')
     419:                             c = c * 8 + *cp++ - '0';
     420:                         *cp2++ = c;
     421:                         break;
     422:                     case 'b':
     423:                         *cp2++ = '\b';
     424:                         break;
     425:                     case 'f':
     426:                         *cp2++ = '\f';
     427:                         break;
     428:                     case 'n':
     429:                         *cp2++ = '\n';
     430:                         break;
     431:                     case 'r':
     432:                         *cp2++ = '\r';
     433:                         break;
     434:                     case 't':
     435:                         *cp2++ = '\t';
     436:                         break;
     437:                     case 'v':
     438:                         *cp2++ = '\v';
     439:                         break;
     440:                     }
     441:                 else if (c == '^') {
     442:                     c = *cp++;
     443:                     if (c == '?')
     444:                         *cp2++ = '\177';
     445:                     /* null doesn't show up anyway */
     446:                     else if (c >= 'A' && c <= '_' ||
     447:                          c >= 'a' && c <= 'z')
     448:                         *cp2++ &= 037;
     449:                     else
     450:                         *cp2++ = *--cp;
     451:                 } else
     452:                     *cp2++ = c;
     453:             } else if (c == '"' || c == '\'')
     454:                 quotec = c;
     455:             else if (c == ' ' || c == '\t')
     456:                 break;
     457:             else
     458:                 *cp2++ = c;
     459:         }
     460:         *cp2 = '\0';
     461:         argv[argn++] = savestr(linebuf);
     462:     }
     463:     argv[argn] = NOSTR;
     464:     return argn;
     465: }
     466:
     467: /*
     468:  * scan out a single lexical item and return its token number,
     469:  * updating the string pointer passed **p.  Also, store the value
     470:  * of the number or string scanned in lexnumber or lexstring as
     471:  * appropriate.  In any event, store the scanned `thing' in lexstring.
     472:  */
     473:
     474: struct lex {
     475:     char    l_char;
     476:     char    l_token;
     477: } singles[] = {
     478:     '$',    TDOLLAR,
     479:     '.',    TDOT,
     480:     '^',    TUP,
     481:     '*',    TSTAR,
     482:     '-',    TDASH,
     483:     '+',    TPLUS,
     484:     '(',    TOPEN,
     485:     ')',    TCLOSE,
     486:     0,  0
     487: };
     488:
     489: scan(sp)
     490:     char **sp;
     491: {
     492:     register char *cp, *cp2;
     493:     register int c;
     494:     register struct lex *lp;
     495:     int quotec;
     496:
     497:     if (regretp >= 0) {
     498:         strcpy(lexstring, string_stack[regretp]);
     499:         lexnumber = numberstack[regretp];
     500:         return(regretstack[regretp--]);
     501:     }
     502:     cp = *sp;
     503:     cp2 = lexstring;
     504:     c = *cp++;
     505:
     506:     /*
     507: 	 * strip away leading white space.
     508: 	 */
     509:
     510:     while (c == ' ' || c == '\t')
     511:         c = *cp++;
     512:
     513:     /*
     514: 	 * If no characters remain, we are at end of line,
     515: 	 * so report that.
     516: 	 */
     517:
     518:     if (c == '\0') {
     519:         *sp = --cp;
     520:         return(TEOL);
     521:     }
     522:
     523:     /*
     524: 	 * If the leading character is a digit, scan
     525: 	 * the number and convert it on the fly.
     526: 	 * Return TNUMBER when done.
     527: 	 */
     528:
     529:     if (isdigit(c)) {
     530:         lexnumber = 0;
     531:         while (isdigit(c)) {
     532:             lexnumber = lexnumber*10 + c - '0';
     533:             *cp2++ = c;
     534:             c = *cp++;
     535:         }
     536:         *cp2 = '\0';
     537:         *sp = --cp;
     538:         return(TNUMBER);
     539:     }
     540:
     541:     /*
     542: 	 * Check for single character tokens; return such
     543: 	 * if found.
     544: 	 */
     545:
     546:     for (lp = &singles[0]; lp->l_char != 0; lp++)
     547:         if (c == lp->l_char) {
     548:             lexstring[0] = c;
     549:             lexstring[1] = '\0';
     550:             *sp = cp;
     551:             return(lp->l_token);
     552:         }
     553:
     554:     /*
     555: 	 * We've got a string!  Copy all the characters
     556: 	 * of the string into lexstring, until we see
     557: 	 * a null, space, or tab.
     558: 	 * If the lead character is a " or ', save it
     559: 	 * and scan until you get another.
     560: 	 */
     561:
     562:     quotec = 0;
     563:     if (c == '\'' || c == '"') {
     564:         quotec = c;
     565:         c = *cp++;
     566:     }
     567:     while (c != '\0') {
     568:         if (c == quotec) {
     569:             cp++;
     570:             break;
     571:         }
     572:         if (quotec == 0 && (c == ' ' || c == '\t'))
     573:             break;
     574:         if (cp2 - lexstring < STRINGLEN-1)
     575:             *cp2++ = c;
     576:         c = *cp++;
     577:     }
     578:     if (quotec && c == 0) {
     579:         fprintf(stderr, "Missing %c\n", quotec);
     580:         return TERROR;
     581:     }
     582:     *sp = --cp;
     583:     *cp2 = '\0';
     584:     return(TSTRING);
     585: }
     586:
     587: /*
     588:  * Unscan the named token by pushing it onto the regret stack.
     589:  */
     590:
     591: regret(token)
     592: {
     593:     if (++regretp >= REGDEP)
     594:         panic("Too many regrets");
     595:     regretstack[regretp] = token;
     596:     lexstring[STRINGLEN-1] = '\0';
     597:     string_stack[regretp] = savestr(lexstring);
     598:     numberstack[regretp] = lexnumber;
     599: }
     600:
     601: /*
     602:  * Reset all the scanner global variables.
     603:  */
     604:
     605: scaninit()
     606: {
     607:     regretp = -1;
     608: }
     609:
     610: /*
     611:  * Find the first message whose flags & m == f  and return
     612:  * its message number.
     613:  */
     614:
     615: first(f, m)
     616: {
     617:     register struct message *mp;
     618:
     619:     if (msgCount == 0)
     620:         return 0;
     621:     f &= MDELETED;
     622:     m &= MDELETED;
     623:     for (mp = dot; mp < &message[msgCount]; mp++)
     624:         if ((mp->m_flag & m) == f)
     625:             return mp - message + 1;
     626:     for (mp = dot-1; mp >= &message[0]; mp--)
     627:         if ((mp->m_flag & m) == f)
     628:             return mp - message + 1;
     629:     return 0;
     630: }
     631:
     632: /*
     633:  * See if the passed name sent the passed message number.  Return true
     634:  * if so.
     635:  */
     636:
     637: matchsender(str, mesg)
     638:     char *str;
     639: {
     640:     register char *cp, *cp2, *backup;
     641:
     642:     if (!*str)  /* null string matches nothing instead of everything */
     643:         return 0;
     644:     backup = cp2 = nameof(&message[mesg - 1], 0);
     645:     cp = str;
     646:     while (*cp2) {
     647:         if (*cp == 0)
     648:             return(1);
     649:         if (raise(*cp++) != raise(*cp2++)) {
     650:             cp2 = ++backup;
     651:             cp = str;
     652:         }
     653:     }
     654:     return(*cp == 0);
     655: }
     656:
     657: /*
     658:  * See if the given string matches inside the subject field of the
     659:  * given message.  For the purpose of the scan, we ignore case differences.
     660:  * If it does, return true.  The string search argument is assumed to
     661:  * have the form "/search-string."  If it is of the form "/," we use the
     662:  * previous search string.
     663:  */
     664:
     665: char lastscan[128];
     666:
     667: matchsubj(str, mesg)
     668:     char *str;
     669: {
     670:     register struct message *mp;
     671:     register char *cp, *cp2, *backup;
     672:
     673:     str++;
     674:     if (strlen(str) == 0)
     675:         str = lastscan;
     676:     else
     677:         strcpy(lastscan, str);
     678:     mp = &message[mesg-1];
     679:
     680:     /*
     681: 	 * Now look, ignoring case, for the word in the string.
     682: 	 */
     683:
     684:     cp = str;
     685:     cp2 = hfield("subject", mp);
     686:     if (cp2 == NOSTR)
     687:         return(0);
     688:     backup = cp2;
     689:     while (*cp2) {
     690:         if (*cp == 0)
     691:             return(1);
     692:         if (raise(*cp++) != raise(*cp2++)) {
     693:             cp2 = ++backup;
     694:             cp = str;
     695:         }
     696:     }
     697:     return(*cp == 0);
     698: }
     699:
     700: /*
     701:  * Mark the named message by setting its mark bit.
     702:  */
     703:
     704: mark(mesg)
     705: {
     706:     register int i;
     707:
     708:     i = mesg;
     709:     if (i < 1 || i > msgCount)
     710:         panic("Bad message number to mark");
     711:     message[i-1].m_flag |= MMARK;
     712: }
     713:
     714: /*
     715:  * Unmark the named message.
     716:  */
     717:
     718: unmark(mesg)
     719: {
     720:     register int i;
     721:
     722:     i = mesg;
     723:     if (i < 1 || i > msgCount)
     724:         panic("Bad message number to unmark");
     725:     message[i-1].m_flag &= ~MMARK;
     726: }
     727:
     728: /*
     729:  * Return the message number corresponding to the passed meta character.
     730:  */
     731:
     732: metamess(meta, f)
     733: {
     734:     register int c, m;
     735:     register struct message *mp;
     736:
     737:     c = meta;
     738:     switch (c) {
     739:     case '^':
     740:         /*
     741: 		 * First 'good' message left.
     742: 		 */
     743:         for (mp = &message[0]; mp < &message[msgCount]; mp++)
     744:             if ((mp->m_flag & MDELETED) == f)
     745:                 return(mp - &message[0] + 1);
     746:         printf("No applicable messages\n");
     747:         return(-1);
     748:
     749:     case '$':
     750:         /*
     751: 		 * Last 'good message left.
     752: 		 */
     753:         for (mp = &message[msgCount-1]; mp >= &message[0]; mp--)
     754:             if ((mp->m_flag & MDELETED) == f)
     755:                 return(mp - &message[0] + 1);
     756:         printf("No applicable messages\n");
     757:         return(-1);
     758:
     759:     case '.':
     760:         /*
     761: 		 * Current message.
     762: 		 */
     763:         m = dot - &message[0] + 1;
     764:         if ((dot->m_flag & MDELETED) != f) {
     765:             printf("%d: Inappropriate message\n", m);
     766:             return(-1);
     767:         }
     768:         return(m);
     769:
     770:     default:
     771:         printf("Unknown metachar (%c)\n", c);
     772:         return(-1);
     773:     }
     774: }

#### Defined functions

check defined in line 359; used 2 times

- in line 144, 153

evalcol defined in line 342; used 1 times

- in line 200

first defined in line 615; used 4 times

- in /usr/src/ucb/Mail/cmd2.c line 167, 321
- in /usr/src/ucb/Mail/collect.c line 515
- in /usr/src/ucb/Mail/lex.c line 336

getmsglist defined in line 54; used 4 times

- in /usr/src/ucb/Mail/cmd2.c line 174
- in /usr/src/ucb/Mail/collect.c line 512
- in /usr/src/ucb/Mail/lex.c line 333, 356

getrawlist defined in line 380; used 2 times

- in /usr/src/ucb/Mail/lex.c line 375
- in /usr/src/ucb/Mail/popen.c line 207

mark defined in line 704; used 6 times

- in line 148, 158, 176, 189, 239, 258

markall defined in line 112; used 1 times

- in line 65

matchsender defined in line 637; used 1 times

- in line 275

matchsubj defined in line 667; used 1 times

- in line 269

metamess defined in line 732; used 1 times

- in line 215

regret defined in line 591; used 1 times

- in line 156

scan defined in line 489; used 3 times

- in line 129, 155, 231

scaninit defined in line 605; used 1 times

- in line 128

unmark defined in line 718; used 3 times

- in line 124, 281, 318

#### Defined variables

coltab defined in line 101; used 3 times

- in line 314, 328, 348

lastcolmod defined in line 110; used 2 times

- in line 233, 347

lastscan defined in line 665; used 2 times

- in line 675-677(2)

sccsid defined in line 35; never used
singles defined in line 477; used 1 times

- in line 546

#### Defined struct's

coltab defined in line 96; used 6 times

- in line 311(2), 325(2), 344(2)

lex defined in line 474; used 2 times

- in line 494(2)

#### Defined macros

CMDELETED defined in line 88; used 1 times

- in line 105

CMNEW defined in line 85; used 1 times

- in line 102

CMOLD defined in line 86; used 1 times

- in line 103

CMREAD defined in line 89; used 1 times

- in line 106

CMUNREAD defined in line 87; used 1 times

- in line 104

Last modified: 1992-10-22 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1373 |