Annotation of src/usr.bin/mail/cmd3.c, Revision 1.11.2.1
1.11.2.1! jason 1: /* $OpenBSD: cmd3.c,v 1.12 2000/06/30 16:00:16 millert Exp $ */
1.5 millert 2: /* $NetBSD: cmd3.c,v 1.8 1997/07/09 05:29:49 mikel Exp $ */
1.2 deraadt 3:
1.1 deraadt 4: /*
5: * Copyright (c) 1980, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: */
36:
37: #ifndef lint
1.2 deraadt 38: #if 0
1.5 millert 39: static char sccsid[] = "@(#)cmd3.c 8.2 (Berkeley) 4/20/95";
1.2 deraadt 40: #else
1.11.2.1! jason 41: static char rcsid[] = "$OpenBSD: cmd3.c,v 1.12 2000/06/30 16:00:16 millert Exp $";
1.2 deraadt 42: #endif
1.1 deraadt 43: #endif /* not lint */
44:
45: #include "rcv.h"
46: #include "extern.h"
47:
48: /*
49: * Mail -- a mail program
50: *
51: * Still more user commands.
52: */
1.2 deraadt 53: static int diction __P((const void *, const void *));
1.1 deraadt 54:
55: /*
56: * Process a shell escape by saving signals, ignoring signals,
57: * and forking a sh -c
58: */
59: int
1.2 deraadt 60: shell(v)
61: void *v;
1.1 deraadt 62: {
1.2 deraadt 63: char *str = v;
1.1 deraadt 64: sig_t sigint = signal(SIGINT, SIG_IGN);
65: char *shell;
66: char cmd[BUFSIZ];
67:
1.8 millert 68: (void)strncpy(cmd, str, sizeof(cmd) - 1);
69: cmd[sizeof(cmd) - 1] = '\0';
70: if (bangexp(cmd, sizeof(cmd)) < 0)
1.5 millert 71: return(1);
1.7 millert 72: if ((shell = value("SHELL")) == NULL)
1.1 deraadt 73: shell = _PATH_CSHELL;
1.7 millert 74: (void)run_command(shell, 0, -1, -1, "-c", cmd, NULL);
1.6 millert 75: (void)signal(SIGINT, sigint);
1.5 millert 76: puts("!");
77: return(0);
1.1 deraadt 78: }
79:
80: /*
81: * Fork an interactive shell.
82: */
83: /*ARGSUSED*/
84: int
1.2 deraadt 85: dosh(v)
86: void *v;
1.1 deraadt 87: {
88: sig_t sigint = signal(SIGINT, SIG_IGN);
89: char *shell;
90:
1.7 millert 91: if ((shell = value("SHELL")) == NULL)
1.1 deraadt 92: shell = _PATH_CSHELL;
1.7 millert 93: (void)run_command(shell, 0, -1, -1, NULL, NULL, NULL);
1.6 millert 94: (void)signal(SIGINT, sigint);
1.1 deraadt 95: putchar('\n');
1.5 millert 96: return(0);
1.1 deraadt 97: }
98:
99: /*
100: * Expand the shell escape by expanding unescaped !'s into the
101: * last issued command where possible.
102: */
103: int
1.8 millert 104: bangexp(str, strsize)
1.1 deraadt 105: char *str;
1.8 millert 106: size_t strsize;
1.1 deraadt 107: {
108: char bangbuf[BUFSIZ];
1.8 millert 109: static char lastbang[BUFSIZ];
1.10 millert 110: char *cp, *cp2;
111: int n, changed = 0;
1.1 deraadt 112:
113: cp = str;
114: cp2 = bangbuf;
115: n = BUFSIZ;
116: while (*cp) {
117: if (*cp == '!') {
118: if (n < strlen(lastbang)) {
119: overf:
1.5 millert 120: puts("Command buffer overflow");
1.1 deraadt 121: return(-1);
122: }
123: changed++;
1.9 millert 124: strncpy(cp2, lastbang, sizeof(bangbuf) - (cp2 - bangbuf) - 1);
125: bangbuf[sizeof(bangbuf) - 1] = '\0';
1.1 deraadt 126: cp2 += strlen(lastbang);
127: n -= strlen(lastbang);
128: cp++;
129: continue;
130: }
131: if (*cp == '\\' && cp[1] == '!') {
132: if (--n <= 1)
133: goto overf;
134: *cp2++ = '!';
135: cp += 2;
136: changed++;
137: }
138: if (--n <= 1)
139: goto overf;
140: *cp2++ = *cp++;
141: }
142: *cp2 = 0;
143: if (changed) {
1.8 millert 144: (void)printf("!%s\n", bangbuf);
145: (void)fflush(stdout);
1.1 deraadt 146: }
1.8 millert 147: (void)strncpy(str, bangbuf, strsize - 1);
148: str[strsize - 1] = '\0';
149: (void)strncpy(lastbang, bangbuf, sizeof(lastbang) - 1);
1.5 millert 150: lastbang[sizeof(lastbang) - 1] = '\0';
1.1 deraadt 151: return(0);
152: }
153:
154: /*
155: * Print out a nice help message from some file or another.
156: */
157:
158: int
1.2 deraadt 159: help(v)
160: void *v;
1.1 deraadt 161: {
1.10 millert 162: int c;
163: FILE *f;
1.1 deraadt 164:
165: if ((f = Fopen(_PATH_HELP, "r")) == NULL) {
1.5 millert 166: warn(_PATH_HELP);
1.1 deraadt 167: return(1);
168: }
169: while ((c = getc(f)) != EOF)
170: putchar(c);
1.5 millert 171: (void)Fclose(f);
1.1 deraadt 172: return(0);
173: }
174:
175: /*
176: * Change user's working directory.
177: */
178: int
1.2 deraadt 179: schdir(v)
180: void *v;
1.1 deraadt 181: {
1.2 deraadt 182: char **arglist = v;
1.1 deraadt 183: char *cp;
184:
1.7 millert 185: if (*arglist == NULL)
1.1 deraadt 186: cp = homedir;
187: else
1.7 millert 188: if ((cp = expand(*arglist)) == NULL)
1.1 deraadt 189: return(1);
190: if (chdir(cp) < 0) {
1.11.2.1! jason 191: warn("%s", cp);
1.1 deraadt 192: return(1);
193: }
1.5 millert 194: return(0);
1.1 deraadt 195: }
196:
197: int
1.2 deraadt 198: respond(v)
199: void *v;
1.1 deraadt 200: {
1.2 deraadt 201: int *msgvec = v;
1.7 millert 202: if (value("Replyall") == NULL)
1.5 millert 203: return(_respond(msgvec));
1.1 deraadt 204: else
1.5 millert 205: return(_Respond(msgvec));
1.1 deraadt 206: }
207:
208: /*
209: * Reply to a list of messages. Extract each name from the
210: * message header and send them off to mail1()
211: */
212: int
213: _respond(msgvec)
214: int *msgvec;
215: {
216: struct message *mp;
217: char *cp, *rcv, *replyto;
218: char **ap;
219: struct name *np;
220: struct header head;
221:
222: if (msgvec[1] != 0) {
1.5 millert 223: puts("Sorry, can't reply to multiple messages at once");
1.1 deraadt 224: return(1);
225: }
226: mp = &message[msgvec[0] - 1];
227: touch(mp);
228: dot = mp;
1.7 millert 229: if ((rcv = skin(hfield("from", mp))) == NULL)
1.1 deraadt 230: rcv = skin(nameof(mp, 1));
1.7 millert 231: if ((replyto = skin(hfield("reply-to", mp))) != NULL)
1.1 deraadt 232: np = extract(replyto, GTO);
1.7 millert 233: else if ((cp = skin(hfield("to", mp))) != NULL)
1.1 deraadt 234: np = extract(cp, GTO);
235: else
236: np = NIL;
237: np = elide(np);
238: /*
239: * Delete my name from the reply list,
240: * and with it, all my alternate names.
241: */
242: np = delname(np, myname);
243: if (altnames)
244: for (ap = altnames; *ap; ap++)
245: np = delname(np, *ap);
1.7 millert 246: if (np != NIL && replyto == NULL)
1.1 deraadt 247: np = cat(np, extract(rcv, GTO));
248: else if (np == NIL) {
1.7 millert 249: if (replyto != NULL)
1.5 millert 250: puts("Empty reply-to field -- replying to author");
1.1 deraadt 251: np = extract(rcv, GTO);
252: }
253: head.h_to = np;
1.7 millert 254: if ((head.h_subject = hfield("subject", mp)) == NULL)
1.1 deraadt 255: head.h_subject = hfield("subj", mp);
256: head.h_subject = reedit(head.h_subject);
1.7 millert 257: if (replyto == NULL && (cp = skin(hfield("cc", mp))) != NULL) {
1.1 deraadt 258: np = elide(extract(cp, GCC));
259: np = delname(np, myname);
260: if (altnames != 0)
261: for (ap = altnames; *ap; ap++)
262: np = delname(np, *ap);
263: head.h_cc = np;
264: } else
265: head.h_cc = NIL;
266: head.h_bcc = NIL;
267: head.h_smopts = NIL;
268: mail1(&head, 1);
269: return(0);
270: }
271:
272: /*
273: * Modify the subject we are replying to to begin with Re: if
274: * it does not already.
275: */
276: char *
277: reedit(subj)
1.10 millert 278: char *subj;
1.1 deraadt 279: {
280: char *newsubj;
281:
1.7 millert 282: if (subj == NULL)
283: return(NULL);
1.1 deraadt 284: if ((subj[0] == 'r' || subj[0] == 'R') &&
285: (subj[1] == 'e' || subj[1] == 'E') &&
286: subj[2] == ':')
1.5 millert 287: return(subj);
1.1 deraadt 288: newsubj = salloc(strlen(subj) + 5);
289: strcpy(newsubj, "Re: ");
290: strcpy(newsubj + 4, subj);
1.5 millert 291: return(newsubj);
1.1 deraadt 292: }
293:
294: /*
295: * Preserve the named messages, so that they will be sent
296: * back to the system mailbox.
297: */
298: int
1.2 deraadt 299: preserve(v)
300: void *v;
1.1 deraadt 301: {
1.2 deraadt 302: int *msgvec = v;
1.10 millert 303: int *ip, mesg;
304: struct message *mp;
1.1 deraadt 305:
306: if (edit) {
1.5 millert 307: puts("Cannot \"preserve\" in edit mode");
1.1 deraadt 308: return(1);
309: }
310: for (ip = msgvec; *ip != NULL; ip++) {
311: mesg = *ip;
312: mp = &message[mesg-1];
313: mp->m_flag |= MPRESERVE;
314: mp->m_flag &= ~MBOX;
315: dot = mp;
316: }
317: return(0);
318: }
319:
320: /*
321: * Mark all given messages as unread.
322: */
323: int
1.2 deraadt 324: unread(v)
325: void *v;
1.1 deraadt 326: {
1.2 deraadt 327: int *msgvec = v;
1.10 millert 328: int *ip;
1.1 deraadt 329:
330: for (ip = msgvec; *ip != NULL; ip++) {
331: dot = &message[*ip-1];
332: dot->m_flag &= ~(MREAD|MTOUCH);
333: dot->m_flag |= MSTATUS;
334: }
335: return(0);
336: }
337:
338: /*
339: * Print the size of each message.
340: */
341: int
1.2 deraadt 342: messize(v)
343: void *v;
1.1 deraadt 344: {
1.2 deraadt 345: int *msgvec = v;
1.10 millert 346: struct message *mp;
347: int *ip, mesg;
1.1 deraadt 348:
349: for (ip = msgvec; *ip != NULL; ip++) {
350: mesg = *ip;
351: mp = &message[mesg-1];
1.3 millert 352: printf("%d: %d/%d\n", mesg, mp->m_lines, mp->m_size);
1.1 deraadt 353: }
354: return(0);
355: }
356:
357: /*
358: * Quit quickly. If we are sourcing, just pop the input level
359: * by returning an error.
360: */
361: int
1.2 deraadt 362: rexit(v)
363: void *v;
1.1 deraadt 364: {
365: if (sourcing)
366: return(1);
1.2 deraadt 367: exit(0);
1.1 deraadt 368: /*NOTREACHED*/
369: }
370:
371: /*
372: * Set or display a variable value. Syntax is similar to that
373: * of csh.
374: */
375: int
1.2 deraadt 376: set(v)
377: void *v;
1.1 deraadt 378: {
1.2 deraadt 379: char **arglist = v;
1.10 millert 380: struct var *vp;
381: char *cp, *cp2;
1.1 deraadt 382: char varbuf[BUFSIZ], **ap, **p;
383: int errs, h, s;
384:
1.7 millert 385: if (*arglist == NULL) {
1.1 deraadt 386: for (h = 0, s = 1; h < HSHSIZE; h++)
387: for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
388: s++;
1.6 millert 389: ap = (char **)salloc(s * sizeof(*ap));
1.1 deraadt 390: for (h = 0, p = ap; h < HSHSIZE; h++)
391: for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
392: *p++ = vp->v_name;
1.7 millert 393: *p = NULL;
1.1 deraadt 394: sort(ap);
1.7 millert 395: for (p = ap; *p != NULL; p++)
1.1 deraadt 396: printf("%s\t%s\n", *p, value(*p));
397: return(0);
398: }
399: errs = 0;
1.7 millert 400: for (ap = arglist; *ap != NULL; ap++) {
1.1 deraadt 401: cp = *ap;
402: cp2 = varbuf;
403: while (*cp != '=' && *cp != '\0')
404: *cp2++ = *cp++;
405: *cp2 = '\0';
406: if (*cp == '\0')
407: cp = "";
408: else
409: cp++;
410: if (equal(varbuf, "")) {
1.5 millert 411: puts("Non-null variable name required");
1.1 deraadt 412: errs++;
413: continue;
414: }
415: assign(varbuf, cp);
416: }
417: return(errs);
418: }
419:
420: /*
421: * Unset a bunch of variable values.
422: */
423: int
1.2 deraadt 424: unset(v)
425: void *v;
1.1 deraadt 426: {
1.2 deraadt 427: char **arglist = v;
1.10 millert 428: struct var *vp, *vp2;
1.1 deraadt 429: int errs, h;
430: char **ap;
431:
432: errs = 0;
1.7 millert 433: for (ap = arglist; *ap != NULL; ap++) {
1.1 deraadt 434: if ((vp2 = lookup(*ap)) == NOVAR) {
435: if (!sourcing) {
436: printf("\"%s\": undefined variable\n", *ap);
437: errs++;
438: }
439: continue;
440: }
441: h = hash(*ap);
442: if (vp2 == variables[h]) {
443: variables[h] = variables[h]->v_link;
444: vfree(vp2->v_name);
445: vfree(vp2->v_value);
1.6 millert 446: (void)free(vp2);
1.1 deraadt 447: continue;
448: }
449: for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link)
450: ;
451: vp->v_link = vp2->v_link;
452: vfree(vp2->v_name);
453: vfree(vp2->v_value);
1.6 millert 454: (void)free(vp2);
1.1 deraadt 455: }
456: return(errs);
457: }
458:
459: /*
460: * Put add users to a group.
461: */
462: int
1.2 deraadt 463: group(v)
464: void *v;
1.1 deraadt 465: {
1.2 deraadt 466: char **argv = v;
1.10 millert 467: struct grouphead *gh;
468: struct group *gp;
1.1 deraadt 469: char **ap, *gname, **p;
1.10 millert 470: int h, s;
1.1 deraadt 471:
1.7 millert 472: if (*argv == NULL) {
1.1 deraadt 473: for (h = 0, s = 1; h < HSHSIZE; h++)
474: for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
475: s++;
1.6 millert 476: ap = (char **)salloc(s * sizeof(*ap));
1.1 deraadt 477: for (h = 0, p = ap; h < HSHSIZE; h++)
478: for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
479: *p++ = gh->g_name;
1.7 millert 480: *p = NULL;
1.1 deraadt 481: sort(ap);
1.7 millert 482: for (p = ap; *p != NULL; p++)
1.1 deraadt 483: printgroup(*p);
484: return(0);
485: }
1.7 millert 486: if (argv[1] == NULL) {
1.1 deraadt 487: printgroup(*argv);
488: return(0);
489: }
490: gname = *argv;
491: h = hash(gname);
492: if ((gh = findgroup(gname)) == NOGRP) {
1.6 millert 493: gh = (struct grouphead *)calloc(sizeof(*gh), 1);
1.1 deraadt 494: gh->g_name = vcopy(gname);
495: gh->g_list = NOGE;
496: gh->g_link = groups[h];
497: groups[h] = gh;
498: }
499:
500: /*
501: * Insert names from the command list into the group.
502: * Who cares if there are duplicates? They get tossed
503: * later anyway.
504: */
505:
1.7 millert 506: for (ap = argv+1; *ap != NULL; ap++) {
1.6 millert 507: gp = (struct group *)calloc(sizeof(*gp), 1);
1.1 deraadt 508: gp->ge_name = vcopy(*ap);
509: gp->ge_link = gh->g_list;
510: gh->g_list = gp;
511: }
512: return(0);
513: }
514:
515: /*
516: * Sort the passed string vecotor into ascending dictionary
517: * order.
518: */
519: void
520: sort(list)
521: char **list;
522: {
1.10 millert 523: char **ap;
1.1 deraadt 524:
1.7 millert 525: for (ap = list; *ap != NULL; ap++)
1.1 deraadt 526: ;
527: if (ap-list < 2)
528: return;
529: qsort(list, ap-list, sizeof(*list), diction);
530: }
531:
532: /*
533: * Do a dictionary order comparison of the arguments from
534: * qsort.
535: */
1.2 deraadt 536: static int
1.1 deraadt 537: diction(a, b)
538: const void *a, *b;
539: {
540: return(strcmp(*(char **)a, *(char **)b));
541: }
542:
543: /*
544: * The do nothing command for comments.
545: */
546:
547: /*ARGSUSED*/
548: int
1.2 deraadt 549: null(v)
550: void *v;
1.1 deraadt 551: {
1.5 millert 552: return(0);
1.1 deraadt 553: }
554:
555: /*
556: * Change to another file. With no argument, print information about
557: * the current file.
558: */
559: int
1.2 deraadt 560: file(v)
561: void *v;
1.1 deraadt 562: {
1.2 deraadt 563: char **argv = v;
1.1 deraadt 564:
1.7 millert 565: if (argv[0] == NULL) {
1.5 millert 566: newfileinfo(0);
1.11 millert 567: clearnew();
1.5 millert 568: return(0);
1.1 deraadt 569: }
570: if (setfile(*argv) < 0)
1.5 millert 571: return(1);
1.1 deraadt 572: announce();
1.5 millert 573: return(0);
1.1 deraadt 574: }
575:
576: /*
577: * Expand file names like echo
578: */
579: int
1.2 deraadt 580: echo(v)
581: void *v;
1.1 deraadt 582: {
1.2 deraadt 583: char **argv = v;
1.10 millert 584: char **ap, *cp;
1.1 deraadt 585:
1.7 millert 586: for (ap = argv; *ap != NULL; ap++) {
1.1 deraadt 587: cp = *ap;
1.7 millert 588: if ((cp = expand(cp)) != NULL) {
1.1 deraadt 589: if (ap != argv)
590: putchar(' ');
1.5 millert 591: fputs(cp, stdout);
1.1 deraadt 592: }
593: }
594: putchar('\n');
1.5 millert 595: return(0);
1.1 deraadt 596: }
597:
598: int
1.2 deraadt 599: Respond(v)
600: void *v;
1.1 deraadt 601: {
1.2 deraadt 602: int *msgvec = v;
1.7 millert 603: if (value("Replyall") == NULL)
1.5 millert 604: return(_Respond(msgvec));
1.1 deraadt 605: else
1.5 millert 606: return(_respond(msgvec));
1.1 deraadt 607: }
608:
609: /*
610: * Reply to a series of messages by simply mailing to the senders
611: * and not messing around with the To: and Cc: lists as in normal
612: * reply.
613: */
614: int
615: _Respond(msgvec)
616: int msgvec[];
617: {
618: struct header head;
619: struct message *mp;
1.10 millert 620: int *ap;
621: char *cp;
1.1 deraadt 622:
623: head.h_to = NIL;
624: for (ap = msgvec; *ap != 0; ap++) {
625: mp = &message[*ap - 1];
626: touch(mp);
627: dot = mp;
1.7 millert 628: if ((cp = skin(hfield("from", mp))) == NULL)
1.1 deraadt 629: cp = skin(nameof(mp, 2));
630: head.h_to = cat(head.h_to, extract(cp, GTO));
631: }
632: if (head.h_to == NIL)
1.5 millert 633: return(0);
1.1 deraadt 634: mp = &message[msgvec[0] - 1];
1.7 millert 635: if ((head.h_subject = hfield("subject", mp)) == NULL)
1.1 deraadt 636: head.h_subject = hfield("subj", mp);
637: head.h_subject = reedit(head.h_subject);
638: head.h_cc = NIL;
639: head.h_bcc = NIL;
640: head.h_smopts = NIL;
641: mail1(&head, 1);
1.5 millert 642: return(0);
1.1 deraadt 643: }
644:
645: /*
646: * Conditional commands. These allow one to parameterize one's
647: * .mailrc and do some things if sending, others if receiving.
648: */
649: int
1.2 deraadt 650: ifcmd(v)
651: void *v;
1.1 deraadt 652: {
1.2 deraadt 653: char **argv = v;
1.10 millert 654: char *cp;
1.1 deraadt 655:
656: if (cond != CANY) {
1.5 millert 657: puts("Illegal nested \"if\"");
1.1 deraadt 658: return(1);
659: }
660: cond = CANY;
661: cp = argv[0];
662: switch (*cp) {
663: case 'r': case 'R':
664: cond = CRCV;
665: break;
666:
667: case 's': case 'S':
668: cond = CSEND;
669: break;
670:
671: default:
672: printf("Unrecognized if-keyword: \"%s\"\n", cp);
673: return(1);
674: }
675: return(0);
676: }
677:
678: /*
679: * Implement 'else'. This is pretty simple -- we just
680: * flip over the conditional flag.
681: */
682: int
1.2 deraadt 683: elsecmd(v)
684: void *v;
1.1 deraadt 685: {
686:
687: switch (cond) {
688: case CANY:
1.5 millert 689: puts("\"Else\" without matching \"if\"");
1.1 deraadt 690: return(1);
691:
692: case CSEND:
693: cond = CRCV;
694: break;
695:
696: case CRCV:
697: cond = CSEND;
698: break;
699:
700: default:
1.5 millert 701: puts("mail's idea of conditions is screwed up");
1.1 deraadt 702: cond = CANY;
703: break;
704: }
705: return(0);
706: }
707:
708: /*
709: * End of if statement. Just set cond back to anything.
710: */
711: int
1.2 deraadt 712: endifcmd(v)
713: void *v;
1.1 deraadt 714: {
715:
716: if (cond == CANY) {
1.5 millert 717: puts("\"Endif\" without matching \"if\"");
1.1 deraadt 718: return(1);
719: }
720: cond = CANY;
721: return(0);
722: }
723:
724: /*
725: * Set the list of alternate names.
726: */
727: int
1.2 deraadt 728: alternates(v)
729: void *v;
1.1 deraadt 730: {
1.2 deraadt 731: char **namelist = v;
1.10 millert 732: char **ap, **ap2, *cp;
733: int c;
1.1 deraadt 734:
735: c = argcount(namelist) + 1;
736: if (c == 1) {
737: if (altnames == 0)
738: return(0);
739: for (ap = altnames; *ap; ap++)
740: printf("%s ", *ap);
1.5 millert 741: putchar('\n');
1.1 deraadt 742: return(0);
743: }
744: if (altnames != 0)
1.6 millert 745: (void)free(altnames);
746: altnames = (char **)calloc(c, sizeof(char *));
1.1 deraadt 747: for (ap = namelist, ap2 = altnames; *ap; ap++, ap2++) {
1.6 millert 748: cp = (char *)calloc(strlen(*ap) + 1, sizeof(char));
1.1 deraadt 749: strcpy(cp, *ap);
750: *ap2 = cp;
751: }
752: *ap2 = 0;
753: return(0);
754: }