diff options
Diffstat (limited to 'usr.bin/mail/cmd3.c')
-rw-r--r-- | usr.bin/mail/cmd3.c | 730 |
1 files changed, 0 insertions, 730 deletions
diff --git a/usr.bin/mail/cmd3.c b/usr.bin/mail/cmd3.c deleted file mode 100644 index 54a5d5e..0000000 --- a/usr.bin/mail/cmd3.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - * Copyright (c) 1980, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)cmd3.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#include "rcv.h" -#include "extern.h" - -/* - * Mail -- a mail program - * - * Still more user commands. - */ - -/* - * Process a shell escape by saving signals, ignoring signals, - * and forking a sh -c - */ -int -shell(str) - char *str; -{ - sig_t sigint = signal(SIGINT, SIG_IGN); - char *shell; - char cmd[BUFSIZ]; - - (void) strcpy(cmd, str); - if (bangexp(cmd) < 0) - return 1; - if ((shell = value("SHELL")) == NOSTR) - shell = _PATH_CSHELL; - (void) run_command(shell, 0, -1, -1, "-c", cmd, NOSTR); - (void) signal(SIGINT, sigint); - printf("!\n"); - return 0; -} - -/* - * Fork an interactive shell. - */ -/*ARGSUSED*/ -int -dosh(str) - char *str; -{ - sig_t sigint = signal(SIGINT, SIG_IGN); - char *shell; - - if ((shell = value("SHELL")) == NOSTR) - shell = _PATH_CSHELL; - (void) run_command(shell, 0, -1, -1, NOSTR, NOSTR, NOSTR); - (void) signal(SIGINT, sigint); - putchar('\n'); - return 0; -} - -/* - * Expand the shell escape by expanding unescaped !'s into the - * last issued command where possible. - */ - -char lastbang[128]; - -int -bangexp(str) - char *str; -{ - char bangbuf[BUFSIZ]; - register char *cp, *cp2; - register int n; - int changed = 0; - - cp = str; - cp2 = bangbuf; - n = BUFSIZ; - while (*cp) { - if (*cp == '!') { - if (n < strlen(lastbang)) { -overf: - printf("Command buffer overflow\n"); - return(-1); - } - changed++; - strcpy(cp2, lastbang); - cp2 += strlen(lastbang); - n -= strlen(lastbang); - cp++; - continue; - } - if (*cp == '\\' && cp[1] == '!') { - if (--n <= 1) - goto overf; - *cp2++ = '!'; - cp += 2; - changed++; - } - if (--n <= 1) - goto overf; - *cp2++ = *cp++; - } - *cp2 = 0; - if (changed) { - printf("!%s\n", bangbuf); - fflush(stdout); - } - strcpy(str, bangbuf); - strncpy(lastbang, bangbuf, 128); - lastbang[127] = 0; - return(0); -} - -/* - * Print out a nice help message from some file or another. - */ - -int -help() -{ - register c; - register FILE *f; - - if ((f = Fopen(_PATH_HELP, "r")) == NULL) { - perror(_PATH_HELP); - return(1); - } - while ((c = getc(f)) != EOF) - putchar(c); - Fclose(f); - return(0); -} - -/* - * Change user's working directory. - */ -int -schdir(arglist) - char **arglist; -{ - char *cp; - - if (*arglist == NOSTR) - cp = homedir; - else - if ((cp = expand(*arglist)) == NOSTR) - return(1); - if (chdir(cp) < 0) { - perror(cp); - return(1); - } - return 0; -} - -int -respond(msgvec) - int *msgvec; -{ - if (value("Replyall") == NOSTR) - return (_respond(msgvec)); - else - return (_Respond(msgvec)); -} - -/* - * Reply to a list of messages. Extract each name from the - * message header and send them off to mail1() - */ -int -_respond(msgvec) - int *msgvec; -{ - struct message *mp; - char *cp, *rcv, *replyto; - char **ap; - struct name *np; - struct header head; - - if (msgvec[1] != 0) { - printf("Sorry, can't reply to multiple messages at once\n"); - return(1); - } - mp = &message[msgvec[0] - 1]; - touch(mp); - dot = mp; - if ((rcv = skin(hfield("from", mp))) == NOSTR) - rcv = skin(nameof(mp, 1)); - if ((replyto = skin(hfield("reply-to", mp))) != NOSTR) - np = extract(replyto, GTO); - else if ((cp = skin(hfield("to", mp))) != NOSTR) - np = extract(cp, GTO); - else - np = NIL; - np = elide(np); - /* - * Delete my name from the reply list, - * and with it, all my alternate names. - */ - np = delname(np, myname); - if (altnames) - for (ap = altnames; *ap; ap++) - np = delname(np, *ap); - if (np != NIL && replyto == NOSTR) - np = cat(np, extract(rcv, GTO)); - else if (np == NIL) { - if (replyto != NOSTR) - printf("Empty reply-to field -- replying to author\n"); - np = extract(rcv, GTO); - } - head.h_to = np; - if ((head.h_subject = hfield("subject", mp)) == NOSTR) - head.h_subject = hfield("subj", mp); - head.h_subject = reedit(head.h_subject); - if (replyto == NOSTR && (cp = skin(hfield("cc", mp))) != NOSTR) { - np = elide(extract(cp, GCC)); - np = delname(np, myname); - if (altnames != 0) - for (ap = altnames; *ap; ap++) - np = delname(np, *ap); - head.h_cc = np; - } else - head.h_cc = NIL; - head.h_bcc = NIL; - head.h_smopts = NIL; - mail1(&head, 1); - return(0); -} - -/* - * Modify the subject we are replying to to begin with Re: if - * it does not already. - */ -char * -reedit(subj) - register char *subj; -{ - char *newsubj; - - if (subj == NOSTR) - return NOSTR; - if ((subj[0] == 'r' || subj[0] == 'R') && - (subj[1] == 'e' || subj[1] == 'E') && - subj[2] == ':') - return subj; - newsubj = salloc(strlen(subj) + 5); - strcpy(newsubj, "Re: "); - strcpy(newsubj + 4, subj); - return newsubj; -} - -/* - * Preserve the named messages, so that they will be sent - * back to the system mailbox. - */ -int -preserve(msgvec) - int *msgvec; -{ - register struct message *mp; - register int *ip, mesg; - - if (edit) { - printf("Cannot \"preserve\" in edit mode\n"); - return(1); - } - for (ip = msgvec; *ip != NULL; ip++) { - mesg = *ip; - mp = &message[mesg-1]; - mp->m_flag |= MPRESERVE; - mp->m_flag &= ~MBOX; - dot = mp; - } - return(0); -} - -/* - * Mark all given messages as unread. - */ -int -unread(msgvec) - int msgvec[]; -{ - register int *ip; - - for (ip = msgvec; *ip != NULL; ip++) { - dot = &message[*ip-1]; - dot->m_flag &= ~(MREAD|MTOUCH); - dot->m_flag |= MSTATUS; - } - return(0); -} - -/* - * Print the size of each message. - */ -int -messize(msgvec) - int *msgvec; -{ - register struct message *mp; - register int *ip, mesg; - - for (ip = msgvec; *ip != NULL; ip++) { - mesg = *ip; - mp = &message[mesg-1]; - printf("%d: %d/%ld\n", mesg, mp->m_lines, mp->m_size); - } - return(0); -} - -/* - * Quit quickly. If we are sourcing, just pop the input level - * by returning an error. - */ -int -rexit(e) - int e; -{ - if (sourcing) - return(1); - exit(e); - /*NOTREACHED*/ -} - -/* - * Set or display a variable value. Syntax is similar to that - * of csh. - */ -int -set(arglist) - char **arglist; -{ - register struct var *vp; - register char *cp, *cp2; - char varbuf[BUFSIZ], **ap, **p; - int errs, h, s; - - if (*arglist == NOSTR) { - for (h = 0, s = 1; h < HSHSIZE; h++) - for (vp = variables[h]; vp != NOVAR; vp = vp->v_link) - s++; - ap = (char **) salloc(s * sizeof *ap); - for (h = 0, p = ap; h < HSHSIZE; h++) - for (vp = variables[h]; vp != NOVAR; vp = vp->v_link) - *p++ = vp->v_name; - *p = NOSTR; - sort(ap); - for (p = ap; *p != NOSTR; p++) - printf("%s\t%s\n", *p, value(*p)); - return(0); - } - errs = 0; - for (ap = arglist; *ap != NOSTR; ap++) { - cp = *ap; - cp2 = varbuf; - while (*cp != '=' && *cp != '\0') - *cp2++ = *cp++; - *cp2 = '\0'; - if (*cp == '\0') - cp = ""; - else - cp++; - if (equal(varbuf, "")) { - printf("Non-null variable name required\n"); - errs++; - continue; - } - assign(varbuf, cp); - } - return(errs); -} - -/* - * Unset a bunch of variable values. - */ -int -unset(arglist) - char **arglist; -{ - register struct var *vp, *vp2; - int errs, h; - char **ap; - - errs = 0; - for (ap = arglist; *ap != NOSTR; ap++) { - if ((vp2 = lookup(*ap)) == NOVAR) { - if (!sourcing) { - printf("\"%s\": undefined variable\n", *ap); - errs++; - } - continue; - } - h = hash(*ap); - if (vp2 == variables[h]) { - variables[h] = variables[h]->v_link; - vfree(vp2->v_name); - vfree(vp2->v_value); - free((char *)vp2); - continue; - } - for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link) - ; - vp->v_link = vp2->v_link; - vfree(vp2->v_name); - vfree(vp2->v_value); - free((char *) vp2); - } - return(errs); -} - -/* - * Put add users to a group. - */ -int -group(argv) - char **argv; -{ - register struct grouphead *gh; - register struct group *gp; - register int h; - int s; - char **ap, *gname, **p; - - if (*argv == NOSTR) { - for (h = 0, s = 1; h < HSHSIZE; h++) - for (gh = groups[h]; gh != NOGRP; gh = gh->g_link) - s++; - ap = (char **) salloc(s * sizeof *ap); - for (h = 0, p = ap; h < HSHSIZE; h++) - for (gh = groups[h]; gh != NOGRP; gh = gh->g_link) - *p++ = gh->g_name; - *p = NOSTR; - sort(ap); - for (p = ap; *p != NOSTR; p++) - printgroup(*p); - return(0); - } - if (argv[1] == NOSTR) { - printgroup(*argv); - return(0); - } - gname = *argv; - h = hash(gname); - if ((gh = findgroup(gname)) == NOGRP) { - gh = (struct grouphead *) calloc(sizeof *gh, 1); - gh->g_name = vcopy(gname); - gh->g_list = NOGE; - gh->g_link = groups[h]; - groups[h] = gh; - } - - /* - * Insert names from the command list into the group. - * Who cares if there are duplicates? They get tossed - * later anyway. - */ - - for (ap = argv+1; *ap != NOSTR; ap++) { - gp = (struct group *) calloc(sizeof *gp, 1); - gp->ge_name = vcopy(*ap); - gp->ge_link = gh->g_list; - gh->g_list = gp; - } - return(0); -} - -/* - * Sort the passed string vecotor into ascending dictionary - * order. - */ -void -sort(list) - char **list; -{ - register char **ap; - int diction(); - - for (ap = list; *ap != NOSTR; ap++) - ; - if (ap-list < 2) - return; - qsort(list, ap-list, sizeof(*list), diction); -} - -/* - * Do a dictionary order comparison of the arguments from - * qsort. - */ -int -diction(a, b) - const void *a, *b; -{ - return(strcmp(*(char **)a, *(char **)b)); -} - -/* - * The do nothing command for comments. - */ - -/*ARGSUSED*/ -int -null(e) - int e; -{ - return 0; -} - -/* - * Change to another file. With no argument, print information about - * the current file. - */ -int -file(argv) - register char **argv; -{ - - if (argv[0] == NOSTR) { - newfileinfo(); - return 0; - } - if (setfile(*argv) < 0) - return 1; - announce(); - return 0; -} - -/* - * Expand file names like echo - */ -int -echo(argv) - char **argv; -{ - register char **ap; - register char *cp; - - for (ap = argv; *ap != NOSTR; ap++) { - cp = *ap; - if ((cp = expand(cp)) != NOSTR) { - if (ap != argv) - putchar(' '); - printf("%s", cp); - } - } - putchar('\n'); - return 0; -} - -int -Respond(msgvec) - int *msgvec; -{ - if (value("Replyall") == NOSTR) - return (_Respond(msgvec)); - else - return (_respond(msgvec)); -} - -/* - * Reply to a series of messages by simply mailing to the senders - * and not messing around with the To: and Cc: lists as in normal - * reply. - */ -int -_Respond(msgvec) - int msgvec[]; -{ - struct header head; - struct message *mp; - register int *ap; - register char *cp; - - head.h_to = NIL; - for (ap = msgvec; *ap != 0; ap++) { - mp = &message[*ap - 1]; - touch(mp); - dot = mp; - if ((cp = skin(hfield("from", mp))) == NOSTR) - cp = skin(nameof(mp, 2)); - head.h_to = cat(head.h_to, extract(cp, GTO)); - } - if (head.h_to == NIL) - return 0; - mp = &message[msgvec[0] - 1]; - if ((head.h_subject = hfield("subject", mp)) == NOSTR) - head.h_subject = hfield("subj", mp); - head.h_subject = reedit(head.h_subject); - head.h_cc = NIL; - head.h_bcc = NIL; - head.h_smopts = NIL; - mail1(&head, 1); - return 0; -} - -/* - * Conditional commands. These allow one to parameterize one's - * .mailrc and do some things if sending, others if receiving. - */ -int -ifcmd(argv) - char **argv; -{ - register char *cp; - - if (cond != CANY) { - printf("Illegal nested \"if\"\n"); - return(1); - } - cond = CANY; - cp = argv[0]; - switch (*cp) { - case 'r': case 'R': - cond = CRCV; - break; - - case 's': case 'S': - cond = CSEND; - break; - - default: - printf("Unrecognized if-keyword: \"%s\"\n", cp); - return(1); - } - return(0); -} - -/* - * Implement 'else'. This is pretty simple -- we just - * flip over the conditional flag. - */ -int -elsecmd() -{ - - switch (cond) { - case CANY: - printf("\"Else\" without matching \"if\"\n"); - return(1); - - case CSEND: - cond = CRCV; - break; - - case CRCV: - cond = CSEND; - break; - - default: - printf("Mail's idea of conditions is screwed up\n"); - cond = CANY; - break; - } - return(0); -} - -/* - * End of if statement. Just set cond back to anything. - */ -int -endifcmd() -{ - - if (cond == CANY) { - printf("\"Endif\" without matching \"if\"\n"); - return(1); - } - cond = CANY; - return(0); -} - -/* - * Set the list of alternate names. - */ -int -alternates(namelist) - char **namelist; -{ - register int c; - register char **ap, **ap2, *cp; - - c = argcount(namelist) + 1; - if (c == 1) { - if (altnames == 0) - return(0); - for (ap = altnames; *ap; ap++) - printf("%s ", *ap); - printf("\n"); - return(0); - } - if (altnames != 0) - free((char *) altnames); - altnames = (char **) calloc((unsigned) c, sizeof (char *)); - for (ap = namelist, ap2 = altnames; *ap; ap++, ap2++) { - cp = (char *) calloc((unsigned) strlen(*ap) + 1, sizeof (char)); - strcpy(cp, *ap); - *ap2 = cp; - } - *ap2 = 0; - return(0); -} |