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

##### Functions

    cat               X
    count             X
    delname           X
    detract           X
    elide             X
    extract           X
    gexpand           X
    isfileaddr        X
    nalloc            X
    outof             X
    put               X
    tailof            X
    unpack            X
    usermap           X
    yankword          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[] = "@(#)names.c	5.16 (Berkeley) 6/25/90";
      36: #endif
      37:
      38: /*
      39:  * Mail -- a mail program
      40:  *
      41:  * Handle name lists.
      42:  */
      43:
      44: #include "rcv.h"
      45:
      46: /*
      47:  * Allocate a single element of a name list,
      48:  * initialize its name field to the passed
      49:  * name and return it.
      50:  */
      51: struct name *
      52: nalloc(str, ntype)
      53:     char str[];
      54: {
      55:     register struct name *np;
      56:
      57:     np = (struct name *) salloc(sizeof *np);
      58:     np->n_flink = NIL;
      59:     np->n_blink = NIL;
      60:     np->n_type = ntype;
      61:     np->n_name = savestr(str);
      62:     return(np);
      63: }
      64:
      65: /*
      66:  * Find the tail of a list and return it.
      67:  */
      68: struct name *
      69: tailof(name)
      70:     struct name *name;
      71: {
      72:     register struct name *np;
      73:
      74:     np = name;
      75:     if (np == NIL)
      76:         return(NIL);
      77:     while (np->n_flink != NIL)
      78:         np = np->n_flink;
      79:     return(np);
      80: }
      81:
      82: /*
      83:  * Extract a list of names from a line,
      84:  * and make a list of names from it.
      85:  * Return the list or NIL if none found.
      86:  */
      87: struct name *
      88: extract(line, ntype)
      89:     char line[];
      90: {
      91:     register char *cp;
      92:     register struct name *top, *np, *t;
      93:     char nbuf[BUFSIZ];
      94:
      95:     if (line == NOSTR || *line == '\0')
      96:         return NIL;
      97:     top = NIL;
      98:     np = NIL;
      99:     cp = line;
     100:     while ((cp = yankword(cp, nbuf)) != NOSTR) {
     101:         t = nalloc(nbuf, ntype);
     102:         if (top == NIL)
     103:             top = t;
     104:         else
     105:             np->n_flink = t;
     106:         t->n_blink = np;
     107:         np = t;
     108:     }
     109:     return top;
     110: }
     111:
     112: /*
     113:  * Turn a list of names into a string of the same names.
     114:  */
     115: char *
     116: detract(np, ntype)
     117:     register struct name *np;
     118: {
     119:     register int s;
     120:     register char *cp, *top;
     121:     register struct name *p;
     122:     register int comma;
     123:
     124:     comma = ntype & GCOMMA;
     125:     if (np == NIL)
     126:         return(NOSTR);
     127:     ntype &= ~GCOMMA;
     128:     s = 0;
     129:     if (debug && comma)
     130:         fprintf(stderr, "detract asked to insert commas\n");
     131:     for (p = np; p != NIL; p = p->n_flink) {
     132:         if (ntype && (p->n_type & GMASK) != ntype)
     133:             continue;
     134:         s += strlen(p->n_name) + 1;
     135:         if (comma)
     136:             s++;
     137:     }
     138:     if (s == 0)
     139:         return(NOSTR);
     140:     s += 2;
     141:     top = salloc(s);
     142:     cp = top;
     143:     for (p = np; p != NIL; p = p->n_flink) {
     144:         if (ntype && (p->n_type & GMASK) != ntype)
     145:             continue;
     146:         cp = copy(p->n_name, cp);
     147:         if (comma && p->n_flink != NIL)
     148:             *cp++ = ',';
     149:         *cp++ = ' ';
     150:     }
     151:     *--cp = 0;
     152:     if (comma && *--cp == ',')
     153:         *cp = 0;
     154:     return(top);
     155: }
     156:
     157: /*
     158:  * Grab a single word (liberal word)
     159:  * Throw away things between ()'s, and take anything between <>.
     160:  */
     161: char *
     162: yankword(ap, wbuf)
     163:     char *ap, wbuf[];
     164: {
     165:     register char *cp, *cp2;
     166:
     167:     cp = ap;
     168:     for (;;) {
     169:         if (*cp == '\0')
     170:             return NOSTR;
     171:         if (*cp == '(') {
     172:             register int nesting = 0;
     173:
     174:             while (*cp != '\0') {
     175:                 switch (*cp++) {
     176:                 case '(':
     177:                     nesting++;
     178:                     break;
     179:                 case ')':
     180:                     --nesting;
     181:                     break;
     182:                 }
     183:                 if (nesting <= 0)
     184:                     break;
     185:             }
     186:         } else if (*cp == ' ' || *cp == '\t' || *cp == ',')
     187:             cp++;
     188:         else
     189:             break;
     190:     }
     191:     if (*cp ==  '<')
     192:         for (cp2 = wbuf; *cp && (*cp2++ = *cp++) != '>';)
     193:             ;
     194:     else
     195:         for (cp2 = wbuf; *cp && !index(" \t,(", *cp); *cp2++ = *cp++)
     196:             ;
     197:     *cp2 = '\0';
     198:     return cp;
     199: }
     200:
     201: /*
     202:  * For each recipient in the passed name list with a /
     203:  * in the name, append the message to the end of the named file
     204:  * and remove him from the recipient list.
     205:  *
     206:  * Recipients whose name begins with | are piped through the given
     207:  * program and removed.
     208:  */
     209: struct name *
     210: outof(names, fo, hp)
     211:     struct name *names;
     212:     FILE *fo;
     213:     struct header *hp;
     214: {
     215:     register int c;
     216:     register struct name *np, *top;
     217:     time_t now, time();
     218:     char *date, *fname, *ctime();
     219:     FILE *fout, *fin;
     220:     int ispipe;
     221:     extern char tempEdit[];
     222:
     223:     top = names;
     224:     np = names;
     225:     (void) time(&now);
     226:     date = ctime(&now);
     227:     while (np != NIL) {
     228:         if (!isfileaddr(np->n_name) && np->n_name[0] != '|') {
     229:             np = np->n_flink;
     230:             continue;
     231:         }
     232:         ispipe = np->n_name[0] == '|';
     233:         if (ispipe)
     234:             fname = np->n_name+1;
     235:         else
     236:             fname = expand(np->n_name);
     237:
     238:         /*
     239: 		 * See if we have copied the complete message out yet.
     240: 		 * If not, do so.
     241: 		 */
     242:
     243:         if (image < 0) {
     244:             if ((fout = Fopen(tempEdit, "a")) == NULL) {
     245:                 perror(tempEdit);
     246:                 senderr++;
     247:                 goto cant;
     248:             }
     249:             image = open(tempEdit, 2);
     250:             (void) unlink(tempEdit);
     251:             if (image < 0) {
     252:                 perror(tempEdit);
     253:                 senderr++;
     254:                 (void) Fclose(fout);
     255:                 goto cant;
     256:             }
     257:             fprintf(fout, "From %s %s", myname, date);
     258:             puthead(hp, fout, GTO|GSUBJECT|GCC|GNL);
     259:             while ((c = getc(fo)) != EOF)
     260:                 (void) putc(c, fout);
     261:             rewind(fo);
     262:             (void) putc('\n', fout);
     263:             (void) fflush(fout);
     264:             if (ferror(fout))
     265:                 perror(tempEdit);
     266:             (void) Fclose(fout);
     267:         }
     268:
     269:         /*
     270: 		 * Now either copy "image" to the desired file
     271: 		 * or give it as the standard input to the desired
     272: 		 * program as appropriate.
     273: 		 */
     274:
     275:         if (ispipe) {
     276:             int pid;
     277:             char *shell;
     278:
     279:             /*
     280: 			 * XXX
     281: 			 * We can't really reuse the same image file,
     282: 			 * because multiple piped recipients will
     283: 			 * share the same lseek location and trample
     284: 			 * on one another.
     285: 			 */
     286:             if ((shell = value("SHELL")) == NOSTR)
     287:                 shell = _PATH_CSHELL;
     288:             pid = start_command(shell, sigmask(SIGHUP)|
     289:                     sigmask(SIGINT)|sigmask(SIGQUIT),
     290:                 image, -1, "-c", fname, NOSTR);
     291:             if (pid < 0) {
     292:                 senderr++;
     293:                 goto cant;
     294:             }
     295:             free_child(pid);
     296:         } else {
     297:             int f;
     298:             if ((fout = Fopen(fname, "a")) == NULL) {
     299:                 perror(fname);
     300:                 senderr++;
     301:                 goto cant;
     302:             }
     303:             if ((f = dup(image)) < 0) {
     304:                 perror("dup");
     305:                 fin = NULL;
     306:             } else
     307:                 fin = Fdopen(f, "r");
     308:             if (fin == NULL) {
     309:                 fprintf(stderr, "Can't reopen image\n");
     310:                 (void) Fclose(fout);
     311:                 senderr++;
     312:                 goto cant;
     313:             }
     314:             rewind(fin);
     315:             while ((c = getc(fin)) != EOF)
     316:                 (void) putc(c, fout);
     317:             if (ferror(fout))
     318:                 senderr++, perror(fname);
     319:             (void) Fclose(fout);
     320:             (void) Fclose(fin);
     321:         }
     322: cant:
     323:         /*
     324: 		 * In days of old we removed the entry from the
     325: 		 * the list; now for sake of header expansion
     326: 		 * we leave it in and mark it as deleted.
     327: 		 */
     328:         np->n_type |= GDEL;
     329:         np = np->n_flink;
     330:     }
     331:     if (image >= 0) {
     332:         (void) close(image);
     333:         image = -1;
     334:     }
     335:     return(top);
     336: }
     337:
     338: /*
     339:  * Determine if the passed address is a local "send to file" address.
     340:  * If any of the network metacharacters precedes any slashes, it can't
     341:  * be a filename.  We cheat with .'s to allow path names like ./...
     342:  */
     343: isfileaddr(name)
     344:     char *name;
     345: {
     346:     register char *cp;
     347:
     348:     if (*name == '+')
     349:         return 1;
     350:     for (cp = name; *cp; cp++) {
     351:         if (*cp == '!' || *cp == '%' || *cp == '@')
     352:             return 0;
     353:         if (*cp == '/')
     354:             return 1;
     355:     }
     356:     return 0;
     357: }
     358:
     359: /*
     360:  * Map all of the aliased users in the invoker's mailrc
     361:  * file and insert them into the list.
     362:  * Changed after all these months of service to recursively
     363:  * expand names (2/14/80).
     364:  */
     365:
     366: struct name *
     367: usermap(names)
     368:     struct name *names;
     369: {
     370:     register struct name *new, *np, *cp;
     371:     struct grouphead *gh;
     372:     register int metoo;
     373:
     374:     new = NIL;
     375:     np = names;
     376:     metoo = (value("metoo") != NOSTR);
     377:     while (np != NIL) {
     378:         if (np->n_name[0] == '\\') {
     379:             cp = np->n_flink;
     380:             new = put(new, np);
     381:             np = cp;
     382:             continue;
     383:         }
     384:         gh = findgroup(np->n_name);
     385:         cp = np->n_flink;
     386:         if (gh != NOGRP)
     387:             new = gexpand(new, gh, metoo, np->n_type);
     388:         else
     389:             new = put(new, np);
     390:         np = cp;
     391:     }
     392:     return(new);
     393: }
     394:
     395: /*
     396:  * Recursively expand a group name.  We limit the expansion to some
     397:  * fixed level to keep things from going haywire.
     398:  * Direct recursion is not expanded for convenience.
     399:  */
     400:
     401: struct name *
     402: gexpand(nlist, gh, metoo, ntype)
     403:     struct name *nlist;
     404:     struct grouphead *gh;
     405: {
     406:     struct group *gp;
     407:     struct grouphead *ngh;
     408:     struct name *np;
     409:     static int depth;
     410:     char *cp;
     411:
     412:     if (depth > MAXEXP) {
     413:         printf("Expanding alias to depth larger than %d\n", MAXEXP);
     414:         return(nlist);
     415:     }
     416:     depth++;
     417:     for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link) {
     418:         cp = gp->ge_name;
     419:         if (*cp == '\\')
     420:             goto quote;
     421:         if (strcmp(cp, gh->g_name) == 0)
     422:             goto quote;
     423:         if ((ngh = findgroup(cp)) != NOGRP) {
     424:             nlist = gexpand(nlist, ngh, metoo, ntype);
     425:             continue;
     426:         }
     427: quote:
     428:         np = nalloc(cp, ntype);
     429:         /*
     430: 		 * At this point should allow to expand
     431: 		 * to self if only person in group
     432: 		 */
     433:         if (gp == gh->g_list && gp->ge_link == NOGE)
     434:             goto skip;
     435:         if (!metoo && strcmp(cp, myname) == 0)
     436:             np->n_type |= GDEL;
     437: skip:
     438:         nlist = put(nlist, np);
     439:     }
     440:     depth--;
     441:     return(nlist);
     442: }
     443:
     444: /*
     445:  * Concatenate the two passed name lists, return the result.
     446:  */
     447: struct name *
     448: cat(n1, n2)
     449:     struct name *n1, *n2;
     450: {
     451:     register struct name *tail;
     452:
     453:     if (n1 == NIL)
     454:         return(n2);
     455:     if (n2 == NIL)
     456:         return(n1);
     457:     tail = tailof(n1);
     458:     tail->n_flink = n2;
     459:     n2->n_blink = tail;
     460:     return(n1);
     461: }
     462:
     463: /*
     464:  * Unpack the name list onto a vector of strings.
     465:  * Return an error if the name list won't fit.
     466:  */
     467: char **
     468: unpack(np)
     469:     struct name *np;
     470: {
     471:     register char **ap, **top;
     472:     register struct name *n;
     473:     int t, extra, metoo, verbose;
     474:
     475:     n = np;
     476:     if ((t = count(n)) == 0)
     477:         panic("No names to unpack");
     478:     /*
     479: 	 * Compute the number of extra arguments we will need.
     480: 	 * We need at least two extra -- one for "mail" and one for
     481: 	 * the terminating 0 pointer.  Additional spots may be needed
     482: 	 * to pass along -f to the host mailer.
     483: 	 */
     484:     extra = 2;
     485:     extra++;
     486:     metoo = value("metoo") != NOSTR;
     487:     if (metoo)
     488:         extra++;
     489:     verbose = value("verbose") != NOSTR;
     490:     if (verbose)
     491:         extra++;
     492:     top = (char **) salloc((t + extra) * sizeof *top);
     493:     ap = top;
     494:     *ap++ = "send-mail";
     495:     *ap++ = "-i";
     496:     if (metoo)
     497:         *ap++ = "-m";
     498:     if (verbose)
     499:         *ap++ = "-v";
     500:     for (; n != NIL; n = n->n_flink)
     501:         if ((n->n_type & GDEL) == 0)
     502:             *ap++ = n->n_name;
     503:     *ap = NOSTR;
     504:     return(top);
     505: }
     506:
     507: /*
     508:  * Remove all of the duplicates from the passed name list by
     509:  * insertion sorting them, then checking for dups.
     510:  * Return the head of the new list.
     511:  */
     512: struct name *
     513: elide(names)
     514:     struct name *names;
     515: {
     516:     register struct name *np, *t, *new;
     517:     struct name *x;
     518:
     519:     if (names == NIL)
     520:         return(NIL);
     521:     new = names;
     522:     np = names;
     523:     np = np->n_flink;
     524:     if (np != NIL)
     525:         np->n_blink = NIL;
     526:     new->n_flink = NIL;
     527:     while (np != NIL) {
     528:         t = new;
     529:         while (strcasecmp(t->n_name, np->n_name) < 0) {
     530:             if (t->n_flink == NIL)
     531:                 break;
     532:             t = t->n_flink;
     533:         }
     534:
     535:         /*
     536: 		 * If we ran out of t's, put the new entry after
     537: 		 * the current value of t.
     538: 		 */
     539:
     540:         if (strcasecmp(t->n_name, np->n_name) < 0) {
     541:             t->n_flink = np;
     542:             np->n_blink = t;
     543:             t = np;
     544:             np = np->n_flink;
     545:             t->n_flink = NIL;
     546:             continue;
     547:         }
     548:
     549:         /*
     550: 		 * Otherwise, put the new entry in front of the
     551: 		 * current t.  If at the front of the list,
     552: 		 * the new guy becomes the new head of the list.
     553: 		 */
     554:
     555:         if (t == new) {
     556:             t = np;
     557:             np = np->n_flink;
     558:             t->n_flink = new;
     559:             new->n_blink = t;
     560:             t->n_blink = NIL;
     561:             new = t;
     562:             continue;
     563:         }
     564:
     565:         /*
     566: 		 * The normal case -- we are inserting into the
     567: 		 * middle of the list.
     568: 		 */
     569:
     570:         x = np;
     571:         np = np->n_flink;
     572:         x->n_flink = t;
     573:         x->n_blink = t->n_blink;
     574:         t->n_blink->n_flink = x;
     575:         t->n_blink = x;
     576:     }
     577:
     578:     /*
     579: 	 * Now the list headed up by new is sorted.
     580: 	 * Go through it and remove duplicates.
     581: 	 */
     582:
     583:     np = new;
     584:     while (np != NIL) {
     585:         t = np;
     586:         while (t->n_flink != NIL &&
     587:                strcasecmp(np->n_name, t->n_flink->n_name) == 0)
     588:             t = t->n_flink;
     589:         if (t == np || t == NIL) {
     590:             np = np->n_flink;
     591:             continue;
     592:         }
     593:
     594:         /*
     595: 		 * Now t points to the last entry with the same name
     596: 		 * as np.  Make np point beyond t.
     597: 		 */
     598:
     599:         np->n_flink = t->n_flink;
     600:         if (t->n_flink != NIL)
     601:             t->n_flink->n_blink = np;
     602:         np = np->n_flink;
     603:     }
     604:     return(new);
     605: }
     606:
     607: /*
     608:  * Put another node onto a list of names and return
     609:  * the list.
     610:  */
     611: struct name *
     612: put(list, node)
     613:     struct name *list, *node;
     614: {
     615:     node->n_flink = list;
     616:     node->n_blink = NIL;
     617:     if (list != NIL)
     618:         list->n_blink = node;
     619:     return(node);
     620: }
     621:
     622: /*
     623:  * Determine the number of undeleted elements in
     624:  * a name list and return it.
     625:  */
     626: count(np)
     627:     register struct name *np;
     628: {
     629:     register int c;
     630:
     631:     for (c = 0; np != NIL; np = np->n_flink)
     632:         if ((np->n_type & GDEL) == 0)
     633:             c++;
     634:     return c;
     635: }
     636:
     637: /*
     638:  * Delete the given name from a namelist.
     639:  */
     640: struct name *
     641: delname(np, name)
     642:     register struct name *np;
     643:     char name[];
     644: {
     645:     register struct name *p;
     646:
     647:     for (p = np; p != NIL; p = p->n_flink)
     648:         if (strcasecmp(p->n_name, name) == 0) {
     649:             if (p->n_blink == NIL) {
     650:                 if (p->n_flink != NIL)
     651:                     p->n_flink->n_blink = NIL;
     652:                 np = p->n_flink;
     653:                 continue;
     654:             }
     655:             if (p->n_flink == NIL) {
     656:                 if (p->n_blink != NIL)
     657:                     p->n_blink->n_flink = NIL;
     658:                 continue;
     659:             }
     660:             p->n_blink->n_flink = p->n_flink;
     661:             p->n_flink->n_blink = p->n_blink;
     662:         }
     663:     return np;
     664: }
     665:
     666: /*
     667:  * Pretty print a name list
     668:  * Uncomment it if you need it.
     669:  */
     670:
     671: /*
     672: prettyprint(name)
     673: 	struct name *name;
     674: {
     675: 	register struct name *np;
     676:
     677: 	np = name;
     678: 	while (np != NIL) {
     679: 		fprintf(stderr, "%s(%d) ", np->n_name, np->n_type);
     680: 		np = np->n_flink;
     681: 	}
     682: 	fprintf(stderr, "\n");
     683: }
     684: */

#### Defined functions

cat defined in line 447; used 16 times

- in /usr/src/ucb/Mail/cmd3.c line 226, 594
- in /usr/src/ucb/Mail/collect.c line 231, 246, 252
- in /usr/src/ucb/Mail/def.h line 314
- in /usr/src/ucb/Mail/main.c line 168, 174, 187-189(2)
- in /usr/src/ucb/Mail/send.c line 321(2), 341, 409-415(3)

count defined in line 626; used 3 times

- in line 476
- in /usr/src/ucb/Mail/send.c line 334, 370

delname defined in line 640; used 5 times

- in /usr/src/ucb/Mail/cmd3.c line 221-224(2), 238-241(2)
- in /usr/src/ucb/Mail/def.h line 315

detract defined in line 115; used 4 times

- in /usr/src/ucb/Mail/def.h line 285
- in /usr/src/ucb/Mail/tty.c line 103, 118, 126

elide defined in line 512; used 4 times

- in /usr/src/ucb/Mail/cmd3.c line 216, 237
- in /usr/src/ucb/Mail/def.h line 316
- in /usr/src/ucb/Mail/send.c line 333

extract defined in line 87; used 14 times

- in /usr/src/ucb/Mail/cmd3.c line 211-213(2), 226-230(2), 237, 594
- in /usr/src/ucb/Mail/collect.c line 231, 246, 252
- in /usr/src/ucb/Mail/def.h line 317
- in /usr/src/ucb/Mail/send.c line 275
- in /usr/src/ucb/Mail/tty.c line 103, 118, 126

gexpand defined in line 401; used 3 times

- in line 387, 424
- in /usr/src/ucb/Mail/def.h line 318

isfileaddr defined in line 343; used 1 times

- in line 228

nalloc defined in line 51; used 10 times

- in line 101, 428
- in /usr/src/ucb/Mail/def.h line 313
- in /usr/src/ucb/Mail/main.c line 168, 174, 187-189(2)
- in /usr/src/ucb/Mail/send.c line 409-415(3)

outof defined in line 209; used 2 times

- in /usr/src/ucb/Mail/def.h line 319
- in /usr/src/ucb/Mail/send.c line 330

put defined in line 611; used 4 times

- in line 380, 389, 438
- in /usr/src/ucb/Mail/def.h line 320

tailof defined in line 68; used 1 times

- in line 457

unpack defined in line 467; used 2 times

- in /usr/src/ucb/Mail/def.h line 281
- in /usr/src/ucb/Mail/send.c line 341

usermap defined in line 366; used 2 times

- in /usr/src/ucb/Mail/def.h line 321
- in /usr/src/ucb/Mail/send.c line 321

yankword defined in line 161; used 2 times

- in line 100
- in /usr/src/ucb/Mail/def.h line 308

#### 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: 1319 |