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

##### Functions

    clob1             X
    clobber           X
    copycmd           X
    core              X
    delete            X
    delm              X
    deltype           X
    igcomp            X
    igfield           X
    ignore1           X
    igshow            X
    next              X
    retfield          X
    save              X
    save1             X
    saveigfield       X
    saveretfield      X
    snarf             X
    swrite            X
    undelete          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[] = "@(#)cmd2.c	5.14 (Berkeley) 6/25/90";
      36: #endif
      37:
      38: #include "rcv.h"
      39: #include <sys/wait.h>
      40:
      41: /*
      42:  * Mail -- a mail program
      43:  *
      44:  * More user commands.
      45:  */
      46:
      47: /*
      48:  * If any arguments were given, go to the next applicable argument
      49:  * following dot, otherwise, go to the next applicable message.
      50:  * If given as first command with no arguments, print first message.
      51:  */
      52:
      53: next(msgvec)
      54:     int *msgvec;
      55: {
      56:     register struct message *mp;
      57:     register int *ip, *ip2;
      58:     int list[2], mdot;
      59:
      60:     if (*msgvec != NULL) {
      61:
      62:         /*
      63: 		 * If some messages were supplied, find the
      64: 		 * first applicable one following dot using
      65: 		 * wrap around.
      66: 		 */
      67:
      68:         mdot = dot - &message[0] + 1;
      69:
      70:         /*
      71: 		 * Find the first message in the supplied
      72: 		 * message list which follows dot.
      73: 		 */
      74:
      75:         for (ip = msgvec; *ip != NULL; ip++)
      76:             if (*ip > mdot)
      77:                 break;
      78:         if (*ip == NULL)
      79:             ip = msgvec;
      80:         ip2 = ip;
      81:         do {
      82:             mp = &message[*ip2 - 1];
      83:             if ((mp->m_flag & MDELETED) == 0) {
      84:                 dot = mp;
      85:                 goto hitit;
      86:             }
      87:             if (*ip2 != NULL)
      88:                 ip2++;
      89:             if (*ip2 == NULL)
      90:                 ip2 = msgvec;
      91:         } while (ip2 != ip);
      92:         printf("No messages applicable\n");
      93:         return(1);
      94:     }
      95:
      96:     /*
      97: 	 * If this is the first command, select message 1.
      98: 	 * Note that this must exist for us to get here at all.
      99: 	 */
     100:
     101:     if (!sawcom)
     102:         goto hitit;
     103:
     104:     /*
     105: 	 * Just find the next good message after dot, no
     106: 	 * wraparound.
     107: 	 */
     108:
     109:     for (mp = dot+1; mp < &message[msgCount]; mp++)
     110:         if ((mp->m_flag & (MDELETED|MSAVED)) == 0)
     111:             break;
     112:     if (mp >= &message[msgCount]) {
     113:         printf("At EOF\n");
     114:         return(0);
     115:     }
     116:     dot = mp;
     117: hitit:
     118:     /*
     119: 	 * Print dot.
     120: 	 */
     121:
     122:     list[0] = dot - &message[0] + 1;
     123:     list[1] = NULL;
     124:     return(type(list));
     125: }
     126:
     127: /*
     128:  * Save a message in a file.  Mark the message as saved
     129:  * so we can discard when the user quits.
     130:  */
     131: save(str)
     132:     char str[];
     133: {
     134:
     135:     return save1(str, 1, "save", saveignore);
     136: }
     137:
     138: /*
     139:  * Copy a message to a file without affected its saved-ness
     140:  */
     141: copycmd(str)
     142:     char str[];
     143: {
     144:
     145:     return save1(str, 0, "copy", saveignore);
     146: }
     147:
     148: /*
     149:  * Save/copy the indicated messages at the end of the passed file name.
     150:  * If mark is true, mark the message "saved."
     151:  */
     152: save1(str, mark, cmd, ignore)
     153:     char str[];
     154:     char *cmd;
     155:     struct ignoretab *ignore;
     156: {
     157:     register int *ip;
     158:     register struct message *mp;
     159:     char *file, *disp;
     160:     int f, *msgvec;
     161:     FILE *obuf;
     162:
     163:     msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec);
     164:     if ((file = snarf(str, &f)) == NOSTR)
     165:         return(1);
     166:     if (!f) {
     167:         *msgvec = first(0, MMNORM);
     168:         if (*msgvec == NULL) {
     169:             printf("No messages to %s.\n", cmd);
     170:             return(1);
     171:         }
     172:         msgvec[1] = NULL;
     173:     }
     174:     if (f && getmsglist(str, msgvec, 0) < 0)
     175:         return(1);
     176:     if ((file = expand(file)) == NOSTR)
     177:         return(1);
     178:     printf("\"%s\" ", file);
     179:     fflush(stdout);
     180:     if (access(file, 0) >= 0)
     181:         disp = "[Appended]";
     182:     else
     183:         disp = "[New file]";
     184:     if ((obuf = Fopen(file, "a")) == NULL) {
     185:         perror(NOSTR);
     186:         return(1);
     187:     }
     188:     for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
     189:         mp = &message[*ip - 1];
     190:         touch(mp);
     191:         if (send(mp, obuf, ignore, NOSTR) < 0) {
     192:             perror(file);
     193:             Fclose(obuf);
     194:             return(1);
     195:         }
     196:         if (mark)
     197:             mp->m_flag |= MSAVED;
     198:     }
     199:     fflush(obuf);
     200:     if (ferror(obuf))
     201:         perror(file);
     202:     Fclose(obuf);
     203:     printf("%s\n", disp);
     204:     return(0);
     205: }
     206:
     207: /*
     208:  * Write the indicated messages at the end of the passed
     209:  * file name, minus header and trailing blank line.
     210:  */
     211:
     212: swrite(str)
     213:     char str[];
     214: {
     215:
     216:     return save1(str, 1, "write", ignoreall);
     217: }
     218:
     219: /*
     220:  * Snarf the file from the end of the command line and
     221:  * return a pointer to it.  If there is no file attached,
     222:  * just return NOSTR.  Put a null in front of the file
     223:  * name so that the message list processing won't see it,
     224:  * unless the file name is the only thing on the line, in
     225:  * which case, return 0 in the reference flag variable.
     226:  */
     227:
     228: char *
     229: snarf(linebuf, flag)
     230:     char linebuf[];
     231:     int *flag;
     232: {
     233:     register char *cp;
     234:
     235:     *flag = 1;
     236:     cp = strlen(linebuf) + linebuf - 1;
     237:
     238:     /*
     239: 	 * Strip away trailing blanks.
     240: 	 */
     241:
     242:     while (cp > linebuf && isspace(*cp))
     243:         cp--;
     244:     *++cp = 0;
     245:
     246:     /*
     247: 	 * Now search for the beginning of the file name.
     248: 	 */
     249:
     250:     while (cp > linebuf && !isspace(*cp))
     251:         cp--;
     252:     if (*cp == '\0') {
     253:         printf("No file specified.\n");
     254:         return(NOSTR);
     255:     }
     256:     if (isspace(*cp))
     257:         *cp++ = 0;
     258:     else
     259:         *flag = 0;
     260:     return(cp);
     261: }
     262:
     263: /*
     264:  * Delete messages.
     265:  */
     266:
     267: delete(msgvec)
     268:     int msgvec[];
     269: {
     270:     delm(msgvec);
     271:     return 0;
     272: }
     273:
     274: /*
     275:  * Delete messages, then type the new dot.
     276:  */
     277:
     278: deltype(msgvec)
     279:     int msgvec[];
     280: {
     281:     int list[2];
     282:     int lastdot;
     283:
     284:     lastdot = dot - &message[0] + 1;
     285:     if (delm(msgvec) >= 0) {
     286:         list[0] = dot - &message[0] + 1;
     287:         if (list[0] > lastdot) {
     288:             touch(dot);
     289:             list[1] = NULL;
     290:             return(type(list));
     291:         }
     292:         printf("At EOF\n");
     293:     } else
     294:         printf("No more messages\n");
     295:     return(0);
     296: }
     297:
     298: /*
     299:  * Delete the indicated messages.
     300:  * Set dot to some nice place afterwards.
     301:  * Internal interface.
     302:  */
     303:
     304: delm(msgvec)
     305:     int *msgvec;
     306: {
     307:     register struct message *mp;
     308:     register *ip;
     309:     int last;
     310:
     311:     last = NULL;
     312:     for (ip = msgvec; *ip != NULL; ip++) {
     313:         mp = &message[*ip - 1];
     314:         touch(mp);
     315:         mp->m_flag |= MDELETED|MTOUCH;
     316:         mp->m_flag &= ~(MPRESERVE|MSAVED|MBOX);
     317:         last = *ip;
     318:     }
     319:     if (last != NULL) {
     320:         dot = &message[last-1];
     321:         last = first(0, MDELETED);
     322:         if (last != NULL) {
     323:             dot = &message[last-1];
     324:             return(0);
     325:         }
     326:         else {
     327:             dot = &message[0];
     328:             return(-1);
     329:         }
     330:     }
     331:
     332:     /*
     333: 	 * Following can't happen -- it keeps lint happy
     334: 	 */
     335:
     336:     return(-1);
     337: }
     338:
     339: /*
     340:  * Undelete the indicated messages.
     341:  */
     342:
     343: undelete(msgvec)
     344:     int *msgvec;
     345: {
     346:     register struct message *mp;
     347:     register *ip;
     348:
     349:     for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
     350:         mp = &message[*ip - 1];
     351:         touch(mp);
     352:         dot = mp;
     353:         mp->m_flag &= ~MDELETED;
     354:     }
     355:     return 0;
     356: }
     357:
     358: /*
     359:  * Interactively dump core on "core"
     360:  */
     361:
     362: core()
     363: {
     364:     int pid;
     365:     extern union wait wait_status;
     366:
     367:     switch (pid = vfork()) {
     368:     case -1:
     369:         perror("fork");
     370:         return(1);
     371:     case 0:
     372:         abort();
     373:         _exit(1);
     374:     }
     375:     printf("Okie dokie");
     376:     fflush(stdout);
     377:     wait_child(pid);
     378:     if (wait_status.w_coredump)
     379:         printf(" -- Core dumped.\n");
     380:     else
     381:         printf(" -- Can't dump core.\n");
     382:     return 0;
     383: }
     384:
     385: /*
     386:  * Clobber as many bytes of stack as the user requests.
     387:  */
     388: clobber(argv)
     389:     char **argv;
     390: {
     391:     register int times;
     392:
     393:     if (argv[0] == 0)
     394:         times = 1;
     395:     else
     396:         times = (atoi(argv[0]) + 511) / 512;
     397:     clob1(times);
     398:     return 0;
     399: }
     400:
     401: /*
     402:  * Clobber the stack.
     403:  */
     404: clob1(n)
     405: {
     406:     char buf[512];
     407:     register char *cp;
     408:
     409:     if (n <= 0)
     410:         return;
     411:     for (cp = buf; cp < &buf[512]; *cp++ = 0xFF)
     412:         ;
     413:     clob1(n - 1);
     414: }
     415:
     416: /*
     417:  * Add the given header fields to the retained list.
     418:  * If no arguments, print the current list of retained fields.
     419:  */
     420: retfield(list)
     421:     char *list[];
     422: {
     423:
     424:     return ignore1(list, ignore + 1, "retained");
     425: }
     426:
     427: /*
     428:  * Add the given header fields to the ignored list.
     429:  * If no arguments, print the current list of ignored fields.
     430:  */
     431: igfield(list)
     432:     char *list[];
     433: {
     434:
     435:     return ignore1(list, ignore, "ignored");
     436: }
     437:
     438: saveretfield(list)
     439:     char *list[];
     440: {
     441:
     442:     return ignore1(list, saveignore + 1, "retained");
     443: }
     444:
     445: saveigfield(list)
     446:     char *list[];
     447: {
     448:
     449:     return ignore1(list, saveignore, "ignored");
     450: }
     451:
     452: ignore1(list, tab, which)
     453:     char *list[];
     454:     struct ignoretab *tab;
     455:     char *which;
     456: {
     457:     char field[BUFSIZ];
     458:     register int h;
     459:     register struct ignore *igp;
     460:     char **ap;
     461:
     462:     if (*list == NOSTR)
     463:         return igshow(tab, which);
     464:     for (ap = list; *ap != 0; ap++) {
     465:         istrcpy(field, *ap);
     466:         if (member(field, tab))
     467:             continue;
     468:         h = hash(field);
     469:         igp = (struct ignore *) calloc(1, sizeof (struct ignore));
     470:         igp->i_field = calloc((unsigned) strlen(field) + 1,
     471:             sizeof (char));
     472:         strcpy(igp->i_field, field);
     473:         igp->i_link = tab->i_head[h];
     474:         tab->i_head[h] = igp;
     475:         tab->i_count++;
     476:     }
     477:     return 0;
     478: }
     479:
     480: /*
     481:  * Print out all currently retained fields.
     482:  */
     483: igshow(tab, which)
     484:     struct ignoretab *tab;
     485:     char *which;
     486: {
     487:     register int h;
     488:     struct ignore *igp;
     489:     char **ap, **ring;
     490:     int igcomp();
     491:
     492:     if (tab->i_count == 0) {
     493:         printf("No fields currently being %s.\n", which);
     494:         return 0;
     495:     }
     496:     ring = (char **) salloc((tab->i_count + 1) * sizeof (char *));
     497:     ap = ring;
     498:     for (h = 0; h < HSHSIZE; h++)
     499:         for (igp = tab->i_head[h]; igp != 0; igp = igp->i_link)
     500:             *ap++ = igp->i_field;
     501:     *ap = 0;
     502:     qsort((char *) ring, tab->i_count, sizeof (char *), igcomp);
     503:     for (ap = ring; *ap != 0; ap++)
     504:         printf("%s\n", *ap);
     505:     return 0;
     506: }
     507:
     508: /*
     509:  * Compare two names for sorting ignored field list.
     510:  */
     511: igcomp(l, r)
     512:     char **l, **r;
     513: {
     514:
     515:     return strcmp(*l, *r);
     516: }

#### Defined functions

clob1 defined in line 404; used 2 times

- in line 397, 413

clobber defined in line 388; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 52, 125

copycmd defined in line 141; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 48, 81

core defined in line 362; used 3 times

- in /usr/src/ucb/Mail/cmdtab.c line 50, 123
- in /usr/src/ucb/Mail/collect.c line 193

delete defined in line 267; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 46, 68

delm defined in line 304; used 2 times

- in line 270, 285

deltype defined in line 278; used 3 times

- in /usr/src/ucb/Mail/cmdtab.c line 49, 69-70(2)

igcomp defined in line 511; used 2 times

- in line 490, 502

igfield defined in line 431; used 3 times

- in /usr/src/ucb/Mail/cmdtab.c line 53, 116-117(2)

ignore1 defined in line 452; used 4 times

- in line 424, 435, 442, 449

igshow defined in line 483; used 1 times

- in line 463

next defined in line 53; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 46, 58

retfield defined in line 420; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 53, 118

save defined in line 131; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 47, 84

save1 defined in line 152; used 3 times

- in line 135, 145, 216

saveigfield defined in line 445; used 3 times

- in /usr/src/ucb/Mail/cmdtab.c line 54, 119-120(2)

saveretfield defined in line 438; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 54, 121

snarf defined in line 228; used 2 times

- in line 164
- in /usr/src/ucb/Mail/def.h line 304

swrite defined in line 212; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 51, 90

undelete defined in line 343; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 46, 71

#### Defined variables

sccsid defined in line 35; never used

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