122446Sdist /*
262083Sbostic * Copyright (c) 1980, 1993
362083Sbostic * The Regents of the University of California. All rights reserved.
433499Sbostic *
542741Sbostic * %sccs.include.redist.c%
622446Sdist */
722446Sdist
834905Sbostic #ifndef lint
9*68818Sdab static char sccsid[] = "@(#)cmd3.c 8.2 (Berkeley) 04/20/95";
1034905Sbostic #endif /* not lint */
111225Skas
121225Skas #include "rcv.h"
1354505Sbostic #include "extern.h"
141225Skas
151225Skas /*
161225Skas * Mail -- a mail program
171225Skas *
181225Skas * Still more user commands.
191225Skas */
201225Skas
211225Skas /*
221225Skas * Process a shell escape by saving signals, ignoring signals,
231225Skas * and forking a sh -c
241225Skas */
2554505Sbostic int
shell(str)261225Skas shell(str)
271225Skas char *str;
281225Skas {
2939612Sedward sig_t sigint = signal(SIGINT, SIG_IGN);
3034963Sedward char *shell;
311271Skas char cmd[BUFSIZ];
321225Skas
3334963Sedward (void) strcpy(cmd, str);
341271Skas if (bangexp(cmd) < 0)
3536554Sedward return 1;
3634963Sedward if ((shell = value("SHELL")) == NOSTR)
3737870Sbostic shell = _PATH_CSHELL;
3834963Sedward (void) run_command(shell, 0, -1, -1, "-c", cmd, NOSTR);
3934963Sedward (void) signal(SIGINT, sigint);
401225Skas printf("!\n");
4134963Sedward return 0;
421225Skas }
431225Skas
441225Skas /*
451225Skas * Fork an interactive shell.
461225Skas */
4731142Sedward /*ARGSUSED*/
4854505Sbostic int
dosh(str)491225Skas dosh(str)
501225Skas char *str;
511225Skas {
5239612Sedward sig_t sigint = signal(SIGINT, SIG_IGN);
5334963Sedward char *shell;
5431142Sedward
5534963Sedward if ((shell = value("SHELL")) == NOSTR)
5637870Sbostic shell = _PATH_CSHELL;
5754505Sbostic (void) run_command(shell, 0, -1, -1, NOSTR, NOSTR, NOSTR);
5834963Sedward (void) signal(SIGINT, sigint);
591225Skas putchar('\n');
6034963Sedward return 0;
611225Skas }
621225Skas
631225Skas /*
641271Skas * Expand the shell escape by expanding unescaped !'s into the
651271Skas * last issued command where possible.
661271Skas */
671271Skas
681271Skas char lastbang[128];
691271Skas
7054505Sbostic int
bangexp(str)711271Skas bangexp(str)
721271Skas char *str;
731271Skas {
741271Skas char bangbuf[BUFSIZ];
751271Skas register char *cp, *cp2;
761271Skas register int n;
771271Skas int changed = 0;
781271Skas
791271Skas cp = str;
801271Skas cp2 = bangbuf;
811271Skas n = BUFSIZ;
821271Skas while (*cp) {
831271Skas if (*cp == '!') {
841271Skas if (n < strlen(lastbang)) {
851271Skas overf:
861271Skas printf("Command buffer overflow\n");
871271Skas return(-1);
881271Skas }
891271Skas changed++;
901271Skas strcpy(cp2, lastbang);
911271Skas cp2 += strlen(lastbang);
921271Skas n -= strlen(lastbang);
931271Skas cp++;
941271Skas continue;
951271Skas }
961271Skas if (*cp == '\\' && cp[1] == '!') {
971271Skas if (--n <= 1)
981271Skas goto overf;
991271Skas *cp2++ = '!';
1001271Skas cp += 2;
1011271Skas changed++;
1021271Skas }
1031271Skas if (--n <= 1)
1041271Skas goto overf;
1051271Skas *cp2++ = *cp++;
1061271Skas }
1071271Skas *cp2 = 0;
1081271Skas if (changed) {
1091271Skas printf("!%s\n", bangbuf);
1101271Skas fflush(stdout);
1111271Skas }
1121271Skas strcpy(str, bangbuf);
1131271Skas strncpy(lastbang, bangbuf, 128);
1141271Skas lastbang[127] = 0;
1151271Skas return(0);
1161271Skas }
1171271Skas
1181271Skas /*
1191225Skas * Print out a nice help message from some file or another.
1201225Skas */
1211225Skas
12254505Sbostic int
help()1231225Skas help()
1241225Skas {
1251225Skas register c;
1261225Skas register FILE *f;
1271225Skas
12843865Sedward if ((f = Fopen(_PATH_HELP, "r")) == NULL) {
12937870Sbostic perror(_PATH_HELP);
1301225Skas return(1);
1311225Skas }
1321225Skas while ((c = getc(f)) != EOF)
1331225Skas putchar(c);
13443865Sedward Fclose(f);
1351225Skas return(0);
1361225Skas }
1371225Skas
1381225Skas /*
1391225Skas * Change user's working directory.
1401225Skas */
14154505Sbostic int
schdir(arglist)14234966Sedward schdir(arglist)
14334966Sedward char **arglist;
1441225Skas {
14534966Sedward char *cp;
1461225Skas
14734966Sedward if (*arglist == NOSTR)
1481225Skas cp = homedir;
1491225Skas else
15034966Sedward if ((cp = expand(*arglist)) == NOSTR)
1511225Skas return(1);
1521225Skas if (chdir(cp) < 0) {
1531225Skas perror(cp);
1541225Skas return(1);
1551225Skas }
15634966Sedward return 0;
1571225Skas }
1581225Skas
15954505Sbostic int
respond(msgvec)16024752Sserge respond(msgvec)
16124752Sserge int *msgvec;
16224752Sserge {
16324752Sserge if (value("Replyall") == NOSTR)
16424752Sserge return (_respond(msgvec));
16524752Sserge else
16624752Sserge return (_Respond(msgvec));
16724752Sserge }
16824752Sserge
1691225Skas /*
1701225Skas * Reply to a list of messages. Extract each name from the
1711225Skas * message header and send them off to mail1()
1721225Skas */
17354505Sbostic int
_respond(msgvec)17424752Sserge _respond(msgvec)
1751225Skas int *msgvec;
1761225Skas {
1771225Skas struct message *mp;
17831142Sedward char *cp, *rcv, *replyto;
17934800Sedward char **ap;
1801225Skas struct name *np;
1811225Skas struct header head;
1821225Skas
1831225Skas if (msgvec[1] != 0) {
1841225Skas printf("Sorry, can't reply to multiple messages at once\n");
1851225Skas return(1);
1861225Skas }
1871225Skas mp = &message[msgvec[0] - 1];
18835107Sedward touch(mp);
1891225Skas dot = mp;
19034800Sedward if ((rcv = skin(hfield("from", mp))) == NOSTR)
19134800Sedward rcv = skin(nameof(mp, 1));
19234800Sedward if ((replyto = skin(hfield("reply-to", mp))) != NOSTR)
19334800Sedward np = extract(replyto, GTO);
19434800Sedward else if ((cp = skin(hfield("to", mp))) != NOSTR)
19534800Sedward np = extract(cp, GTO);
19634800Sedward else
19734800Sedward np = NIL;
19834800Sedward np = elide(np);
1994391Skurt /*
2004391Skurt * Delete my name from the reply list,
2014391Skurt * and with it, all my alternate names.
2024391Skurt */
20334987Sedward np = delname(np, myname);
20410583Sleres if (altnames)
2054391Skurt for (ap = altnames; *ap; ap++)
20634987Sedward np = delname(np, *ap);
20734800Sedward if (np != NIL && replyto == NOSTR)
20834800Sedward np = cat(np, extract(rcv, GTO));
20934800Sedward else if (np == NIL) {
21034800Sedward if (replyto != NOSTR)
2112350Skas printf("Empty reply-to field -- replying to author\n");
21234800Sedward np = extract(rcv, GTO);
2132350Skas }
21434800Sedward head.h_to = np;
21534800Sedward if ((head.h_subject = hfield("subject", mp)) == NOSTR)
2161225Skas head.h_subject = hfield("subj", mp);
2172228Skas head.h_subject = reedit(head.h_subject);
21834800Sedward if (replyto == NOSTR && (cp = skin(hfield("cc", mp))) != NOSTR) {
21934800Sedward np = elide(extract(cp, GCC));
22034987Sedward np = delname(np, myname);
22134800Sedward if (altnames != 0)
22234800Sedward for (ap = altnames; *ap; ap++)
22334987Sedward np = delname(np, *ap);
22434800Sedward head.h_cc = np;
22534800Sedward } else
22634800Sedward head.h_cc = NIL;
22734800Sedward head.h_bcc = NIL;
22834800Sedward head.h_smopts = NIL;
22934800Sedward mail1(&head, 1);
2301225Skas return(0);
2311225Skas }
2321225Skas
2331225Skas /*
2342228Skas * Modify the subject we are replying to to begin with Re: if
2352228Skas * it does not already.
2362228Skas */
2372228Skas char *
reedit(subj)2382228Skas reedit(subj)
23934800Sedward register char *subj;
2402228Skas {
24134800Sedward char *newsubj;
2422228Skas
2432228Skas if (subj == NOSTR)
24434800Sedward return NOSTR;
24534800Sedward if ((subj[0] == 'r' || subj[0] == 'R') &&
24634800Sedward (subj[1] == 'e' || subj[1] == 'E') &&
24734800Sedward subj[2] == ':')
24834800Sedward return subj;
24934800Sedward newsubj = salloc(strlen(subj) + 5);
25034800Sedward strcpy(newsubj, "Re: ");
25134802Sedward strcpy(newsubj + 4, subj);
25234800Sedward return newsubj;
2532228Skas }
2542228Skas
2552228Skas /*
2561225Skas * Preserve the named messages, so that they will be sent
2571225Skas * back to the system mailbox.
2581225Skas */
25954505Sbostic int
preserve(msgvec)2601225Skas preserve(msgvec)
2611225Skas int *msgvec;
2621225Skas {
2631225Skas register struct message *mp;
2641225Skas register int *ip, mesg;
2651225Skas
2661225Skas if (edit) {
2671225Skas printf("Cannot \"preserve\" in edit mode\n");
2681225Skas return(1);
2691225Skas }
2701225Skas for (ip = msgvec; *ip != NULL; ip++) {
2711225Skas mesg = *ip;
2721225Skas mp = &message[mesg-1];
2731225Skas mp->m_flag |= MPRESERVE;
2743320Skas mp->m_flag &= ~MBOX;
2751225Skas dot = mp;
2761225Skas }
2771225Skas return(0);
2781225Skas }
2791225Skas
2801225Skas /*
28124752Sserge * Mark all given messages as unread.
28224752Sserge */
28354505Sbostic int
unread(msgvec)28424752Sserge unread(msgvec)
28524752Sserge int msgvec[];
28624752Sserge {
28724752Sserge register int *ip;
28824752Sserge
28924752Sserge for (ip = msgvec; *ip != NULL; ip++) {
29024752Sserge dot = &message[*ip-1];
29124752Sserge dot->m_flag &= ~(MREAD|MTOUCH);
29224752Sserge dot->m_flag |= MSTATUS;
29324752Sserge }
29424752Sserge return(0);
29524752Sserge }
29624752Sserge
29724752Sserge /*
2981225Skas * Print the size of each message.
2991225Skas */
30054505Sbostic int
messize(msgvec)3011225Skas messize(msgvec)
3021225Skas int *msgvec;
3031225Skas {
3041225Skas register struct message *mp;
3051225Skas register int *ip, mesg;
3061225Skas
3071225Skas for (ip = msgvec; *ip != NULL; ip++) {
3081225Skas mesg = *ip;
3091225Skas mp = &message[mesg-1];
31024752Sserge printf("%d: %d/%ld\n", mesg, mp->m_lines, mp->m_size);
3111225Skas }
3121225Skas return(0);
3131225Skas }
3141225Skas
3151225Skas /*
3161225Skas * Quit quickly. If we are sourcing, just pop the input level
3171225Skas * by returning an error.
3181225Skas */
31954505Sbostic int
rexit(e)3201225Skas rexit(e)
32154505Sbostic int e;
3221225Skas {
3231225Skas if (sourcing)
3241225Skas return(1);
3251225Skas exit(e);
32631142Sedward /*NOTREACHED*/
3271225Skas }
3281225Skas
3291225Skas /*
3301225Skas * Set or display a variable value. Syntax is similar to that
3311225Skas * of csh.
3321225Skas */
33354505Sbostic int
set(arglist)3341225Skas set(arglist)
3351225Skas char **arglist;
3361225Skas {
3371225Skas register struct var *vp;
3381225Skas register char *cp, *cp2;
3391225Skas char varbuf[BUFSIZ], **ap, **p;
3401225Skas int errs, h, s;
3411225Skas
34234987Sedward if (*arglist == NOSTR) {
3431225Skas for (h = 0, s = 1; h < HSHSIZE; h++)
3441225Skas for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
3451225Skas s++;
3461225Skas ap = (char **) salloc(s * sizeof *ap);
3471225Skas for (h = 0, p = ap; h < HSHSIZE; h++)
3481225Skas for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
3491225Skas *p++ = vp->v_name;
3501225Skas *p = NOSTR;
3511225Skas sort(ap);
3521225Skas for (p = ap; *p != NOSTR; p++)
3531225Skas printf("%s\t%s\n", *p, value(*p));
3541225Skas return(0);
3551225Skas }
3561225Skas errs = 0;
3571225Skas for (ap = arglist; *ap != NOSTR; ap++) {
3581225Skas cp = *ap;
3591225Skas cp2 = varbuf;
3601225Skas while (*cp != '=' && *cp != '\0')
3611225Skas *cp2++ = *cp++;
3621225Skas *cp2 = '\0';
3631225Skas if (*cp == '\0')
3641225Skas cp = "";
3651225Skas else
3661225Skas cp++;
3671225Skas if (equal(varbuf, "")) {
3681225Skas printf("Non-null variable name required\n");
3691225Skas errs++;
3701225Skas continue;
3711225Skas }
3721225Skas assign(varbuf, cp);
3731225Skas }
3741225Skas return(errs);
3751225Skas }
3761225Skas
3771225Skas /*
3781225Skas * Unset a bunch of variable values.
3791225Skas */
38054505Sbostic int
unset(arglist)3811225Skas unset(arglist)
3821225Skas char **arglist;
3831225Skas {
3841225Skas register struct var *vp, *vp2;
3851225Skas int errs, h;
3861225Skas char **ap;
3871225Skas
3881225Skas errs = 0;
3891225Skas for (ap = arglist; *ap != NOSTR; ap++) {
3901225Skas if ((vp2 = lookup(*ap)) == NOVAR) {
3911225Skas if (!sourcing) {
3921225Skas printf("\"%s\": undefined variable\n", *ap);
3931225Skas errs++;
3941225Skas }
3951225Skas continue;
3961225Skas }
3971225Skas h = hash(*ap);
3981225Skas if (vp2 == variables[h]) {
3991225Skas variables[h] = variables[h]->v_link;
4001225Skas vfree(vp2->v_name);
4011225Skas vfree(vp2->v_value);
40257659Sbostic free((char *)vp2);
4031225Skas continue;
4041225Skas }
4051225Skas for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link)
4061225Skas ;
4071225Skas vp->v_link = vp2->v_link;
4081225Skas vfree(vp2->v_name);
4091225Skas vfree(vp2->v_value);
41057659Sbostic free((char *) vp2);
4111225Skas }
4121225Skas return(errs);
4131225Skas }
4141225Skas
4151225Skas /*
4161225Skas * Put add users to a group.
4171225Skas */
41854505Sbostic int
group(argv)4191225Skas group(argv)
4201225Skas char **argv;
4211225Skas {
4221225Skas register struct grouphead *gh;
4231225Skas register struct group *gp;
4241225Skas register int h;
4251225Skas int s;
4261225Skas char **ap, *gname, **p;
4271225Skas
42834987Sedward if (*argv == NOSTR) {
4291225Skas for (h = 0, s = 1; h < HSHSIZE; h++)
4301225Skas for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
4311225Skas s++;
4321225Skas ap = (char **) salloc(s * sizeof *ap);
4331225Skas for (h = 0, p = ap; h < HSHSIZE; h++)
4341225Skas for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
4351225Skas *p++ = gh->g_name;
4361225Skas *p = NOSTR;
4371225Skas sort(ap);
4381225Skas for (p = ap; *p != NOSTR; p++)
4391225Skas printgroup(*p);
4401225Skas return(0);
4411225Skas }
44234987Sedward if (argv[1] == NOSTR) {
4431225Skas printgroup(*argv);
4441225Skas return(0);
4451225Skas }
4461225Skas gname = *argv;
4471225Skas h = hash(gname);
4481225Skas if ((gh = findgroup(gname)) == NOGRP) {
4491225Skas gh = (struct grouphead *) calloc(sizeof *gh, 1);
4501225Skas gh->g_name = vcopy(gname);
4511225Skas gh->g_list = NOGE;
4521225Skas gh->g_link = groups[h];
4531225Skas groups[h] = gh;
4541225Skas }
4551225Skas
4561225Skas /*
4571225Skas * Insert names from the command list into the group.
4581225Skas * Who cares if there are duplicates? They get tossed
4591225Skas * later anyway.
4601225Skas */
4611225Skas
4621225Skas for (ap = argv+1; *ap != NOSTR; ap++) {
4631225Skas gp = (struct group *) calloc(sizeof *gp, 1);
4641225Skas gp->ge_name = vcopy(*ap);
4651225Skas gp->ge_link = gh->g_list;
4661225Skas gh->g_list = gp;
4671225Skas }
4681225Skas return(0);
4691225Skas }
4701225Skas
4711225Skas /*
4721225Skas * Sort the passed string vecotor into ascending dictionary
4731225Skas * order.
4741225Skas */
47554505Sbostic void
sort(list)4761225Skas sort(list)
4771225Skas char **list;
4781225Skas {
4791225Skas register char **ap;
4801225Skas int diction();
4811225Skas
4821225Skas for (ap = list; *ap != NOSTR; ap++)
4831225Skas ;
4841225Skas if (ap-list < 2)
4851225Skas return;
48654505Sbostic qsort(list, ap-list, sizeof(*list), diction);
4871225Skas }
4881225Skas
4891225Skas /*
4901225Skas * Do a dictionary order comparison of the arguments from
4911225Skas * qsort.
4921225Skas */
49354505Sbostic int
diction(a,b)4941225Skas diction(a, b)
49554505Sbostic const void *a, *b;
4961225Skas {
49754505Sbostic return(strcmp(*(char **)a, *(char **)b));
4981225Skas }
4991225Skas
5001225Skas /*
5011225Skas * The do nothing command for comments.
5021225Skas */
5031225Skas
50431142Sedward /*ARGSUSED*/
50554505Sbostic int
null(e)5061225Skas null(e)
50754505Sbostic int e;
5081225Skas {
50931142Sedward return 0;
5101225Skas }
5111225Skas
5121225Skas /*
51336554Sedward * Change to another file. With no argument, print information about
51436554Sedward * the current file.
5151225Skas */
51654505Sbostic int
file(argv)5171308Skas file(argv)
51834753Sedward register char **argv;
5191225Skas {
5201225Skas
5211308Skas if (argv[0] == NOSTR) {
522*68818Sdab newfileinfo(0);
52334753Sedward return 0;
5241308Skas }
52536734Sedward if (setfile(*argv) < 0)
52636554Sedward return 1;
52734754Sedward announce();
52831142Sedward return 0;
5291225Skas }
5301225Skas
5311225Skas /*
5321225Skas * Expand file names like echo
5331225Skas */
53454505Sbostic int
echo(argv)5351225Skas echo(argv)
5361225Skas char **argv;
5371225Skas {
5381225Skas register char **ap;
5391225Skas register char *cp;
5401225Skas
5411225Skas for (ap = argv; *ap != NOSTR; ap++) {
5421225Skas cp = *ap;
54334702Sedward if ((cp = expand(cp)) != NOSTR) {
54434702Sedward if (ap != argv)
54534702Sedward putchar(' ');
54634702Sedward printf("%s", cp);
54734702Sedward }
5481225Skas }
54934702Sedward putchar('\n');
55034800Sedward return 0;
5511225Skas }
5521225Skas
55354505Sbostic int
Respond(msgvec)55424752Sserge Respond(msgvec)
55524752Sserge int *msgvec;
55624752Sserge {
55724752Sserge if (value("Replyall") == NOSTR)
55824752Sserge return (_Respond(msgvec));
55924752Sserge else
56024752Sserge return (_respond(msgvec));
56124752Sserge }
56224752Sserge
5631225Skas /*
5641225Skas * Reply to a series of messages by simply mailing to the senders
5651225Skas * and not messing around with the To: and Cc: lists as in normal
5661225Skas * reply.
5671225Skas */
56854505Sbostic int
_Respond(msgvec)56924752Sserge _Respond(msgvec)
5701225Skas int msgvec[];
5711225Skas {
5721225Skas struct header head;
5731225Skas struct message *mp;
57434800Sedward register int *ap;
57534800Sedward register char *cp;
5761225Skas
57734800Sedward head.h_to = NIL;
57834800Sedward for (ap = msgvec; *ap != 0; ap++) {
5791225Skas mp = &message[*ap - 1];
58035107Sedward touch(mp);
5811225Skas dot = mp;
58234800Sedward if ((cp = skin(hfield("from", mp))) == NOSTR)
58334800Sedward cp = skin(nameof(mp, 2));
58434800Sedward head.h_to = cat(head.h_to, extract(cp, GTO));
5851225Skas }
58634800Sedward if (head.h_to == NIL)
58734800Sedward return 0;
5881225Skas mp = &message[msgvec[0] - 1];
58934800Sedward if ((head.h_subject = hfield("subject", mp)) == NOSTR)
59034800Sedward head.h_subject = hfield("subj", mp);
59134800Sedward head.h_subject = reedit(head.h_subject);
59234800Sedward head.h_cc = NIL;
59334800Sedward head.h_bcc = NIL;
59434800Sedward head.h_smopts = NIL;
59534800Sedward mail1(&head, 1);
59634800Sedward return 0;
5971225Skas }
5981521Skas
5991521Skas /*
6001521Skas * Conditional commands. These allow one to parameterize one's
6011521Skas * .mailrc and do some things if sending, others if receiving.
6021521Skas */
60354505Sbostic int
ifcmd(argv)6041521Skas ifcmd(argv)
6051521Skas char **argv;
6061521Skas {
6071521Skas register char *cp;
6081521Skas
6091521Skas if (cond != CANY) {
6101521Skas printf("Illegal nested \"if\"\n");
6111521Skas return(1);
6121521Skas }
6131521Skas cond = CANY;
6141521Skas cp = argv[0];
6151521Skas switch (*cp) {
6161521Skas case 'r': case 'R':
6171521Skas cond = CRCV;
6181521Skas break;
6191521Skas
6201521Skas case 's': case 'S':
6211521Skas cond = CSEND;
6221521Skas break;
6231521Skas
6241521Skas default:
6251521Skas printf("Unrecognized if-keyword: \"%s\"\n", cp);
6261521Skas return(1);
6271521Skas }
6281521Skas return(0);
6291521Skas }
6301521Skas
6311521Skas /*
6321521Skas * Implement 'else'. This is pretty simple -- we just
6331521Skas * flip over the conditional flag.
6341521Skas */
63554505Sbostic int
elsecmd()6361521Skas elsecmd()
6371521Skas {
6381521Skas
6391521Skas switch (cond) {
6401521Skas case CANY:
6411521Skas printf("\"Else\" without matching \"if\"\n");
6421521Skas return(1);
6431521Skas
6441521Skas case CSEND:
6451521Skas cond = CRCV;
6461521Skas break;
6471521Skas
6481521Skas case CRCV:
6491521Skas cond = CSEND;
6501521Skas break;
6511521Skas
6521521Skas default:
6531521Skas printf("Mail's idea of conditions is screwed up\n");
6541521Skas cond = CANY;
6551521Skas break;
6561521Skas }
6571521Skas return(0);
6581521Skas }
6591521Skas
6601521Skas /*
6611521Skas * End of if statement. Just set cond back to anything.
6621521Skas */
66354505Sbostic int
endifcmd()6641521Skas endifcmd()
6651521Skas {
6661521Skas
6671521Skas if (cond == CANY) {
6681521Skas printf("\"Endif\" without matching \"if\"\n");
6691521Skas return(1);
6701521Skas }
6711521Skas cond = CANY;
6721521Skas return(0);
6731521Skas }
6744391Skurt
6754391Skurt /*
6764391Skurt * Set the list of alternate names.
6774391Skurt */
67854505Sbostic int
alternates(namelist)6794391Skurt alternates(namelist)
6804391Skurt char **namelist;
6814391Skurt {
6824391Skurt register int c;
6834391Skurt register char **ap, **ap2, *cp;
6844391Skurt
6854391Skurt c = argcount(namelist) + 1;
6864391Skurt if (c == 1) {
6874391Skurt if (altnames == 0)
6884391Skurt return(0);
6894391Skurt for (ap = altnames; *ap; ap++)
6904391Skurt printf("%s ", *ap);
6914391Skurt printf("\n");
6924391Skurt return(0);
6934391Skurt }
6944391Skurt if (altnames != 0)
69557659Sbostic free((char *) altnames);
69631142Sedward altnames = (char **) calloc((unsigned) c, sizeof (char *));
6974391Skurt for (ap = namelist, ap2 = altnames; *ap; ap++, ap2++) {
69831142Sedward cp = (char *) calloc((unsigned) strlen(*ap) + 1, sizeof (char));
6994391Skurt strcpy(cp, *ap);
7004391Skurt *ap2 = cp;
7014391Skurt }
7024391Skurt *ap2 = 0;
7034391Skurt return(0);
7044391Skurt }
705