-#
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * %sccs.include.redist.c%
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cmd3.c 8.1 (Berkeley) %G%";
+#endif /* not lint */
#include "rcv.h"
-#include <sys/stat.h>
+#include "extern.h"
/*
* Mail -- a mail program
* Still more user commands.
*/
-static char *SccsId = "@(#)cmd3.c 2.3 %G%";
-
/*
* Process a shell escape by saving signals, ignoring signals,
* and forking a sh -c
*/
-
+int
shell(str)
char *str;
{
- int (*sig[2])(), stat[1];
- register int t;
- char *Shell;
+ sig_t sigint = signal(SIGINT, SIG_IGN);
+ char *shell;
char cmd[BUFSIZ];
- strcpy(cmd, str);
+ (void) strcpy(cmd, str);
if (bangexp(cmd) < 0)
- return(-1);
- if ((Shell = value("SHELL")) == NOSTR)
- Shell = SHELL;
- for (t = 2; t < 4; t++)
- sig[t-2] = sigset(t, SIG_IGN);
- t = vfork();
- if (t == 0) {
- for (t = 2; t < 4; t++)
- if (sig[t-2] != SIG_IGN)
- sigsys(t, SIG_DFL);
- execl(Shell, Shell, "-c", cmd, 0);
- perror(Shell);
- _exit(1);
- }
- while (wait(stat) != t)
- ;
- if (t == -1)
- perror("fork");
- for (t = 2; t < 4; t++)
- sigset(t, sig[t-2]);
+ 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);
+ return 0;
}
/*
* Fork an interactive shell.
*/
-
+/*ARGSUSED*/
+int
dosh(str)
char *str;
{
- int (*sig[2])(), stat[1];
- register int t;
- char *Shell;
- if ((Shell = value("SHELL")) == NOSTR)
- Shell = SHELL;
- for (t = 2; t < 4; t++)
- sig[t-2] = sigset(t, SIG_IGN);
- t = vfork();
- if (t == 0) {
- for (t = 2; t < 4; t++)
- if (sig[t-2] != SIG_IGN)
- sigsys(t, SIG_DFL);
- execl(Shell, Shell, 0);
- perror(Shell);
- _exit(1);
- }
- while (wait(stat) != t)
- ;
- if (t == -1)
- perror("fork");
- for (t = 2; t < 4; t++)
- sigsys(t, sig[t-2]);
+ 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);
+ return 0;
}
/*
char lastbang[128];
+int
bangexp(str)
char *str;
{
* Print out a nice help message from some file or another.
*/
+int
help()
{
register c;
register FILE *f;
- if ((f = fopen(HELPFILE, "r")) == NULL) {
- printf("No help just now.\n");
+ if ((f = Fopen(_PATH_HELP, "r")) == NULL) {
+ perror(_PATH_HELP);
return(1);
}
while ((c = getc(f)) != EOF)
putchar(c);
- fclose(f);
+ Fclose(f);
return(0);
}
/*
* Change user's working directory.
*/
-
-schdir(str)
- char *str;
+int
+schdir(arglist)
+ char **arglist;
{
- register char *cp;
+ char *cp;
- for (cp = str; *cp == ' '; cp++)
- ;
- if (*cp == '\0')
+ if (*arglist == NOSTR)
cp = homedir;
else
- if ((cp = expand(cp)) == NOSTR)
+ if ((cp = expand(*arglist)) == NOSTR)
return(1);
if (chdir(cp) < 0) {
perror(cp);
return(1);
}
- return(0);
+ 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()
*/
-
-respond(msgvec)
+int
+_respond(msgvec)
int *msgvec;
{
struct message *mp;
- char *cp, buf[2 * LINESIZE], *rcv, *replyto, **ap;
+ char *cp, *rcv, *replyto;
+ char **ap;
struct name *np;
struct header head;
- char *netmap();
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;
- rcv = nameof(mp, 1);
- replyto = skin(hfield("reply-to", mp));
- strcpy(buf, "");
- if (replyto != NOSTR)
- strcpy(buf, replyto);
- else {
- cp = hfield("to", mp);
- if (cp != NOSTR)
- strcpy(buf, cp);
- }
- np = elide(extract(buf, GTO));
- /* rcv = rename(rcv); */
- mapf(np, rcv);
+ 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 != 0)
+ if (altnames)
for (ap = altnames; *ap; ap++)
np = delname(np, *ap);
- head.h_seq = 1;
- cp = detract(np, 0);
- if (cp != NOSTR && replyto == NOSTR) {
- strcpy(buf, cp);
- strcat(buf, " ");
- strcat(buf, rcv);
- }
- else {
- if (cp == NOSTR && replyto != NOSTR)
+ 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");
- if (cp == NOSTR)
- strcpy(buf, rcv);
- else
- strcpy(buf, cp);
+ np = extract(rcv, GTO);
}
- head.h_to = buf;
- head.h_subject = hfield("subject", mp);
- if (head.h_subject == NOSTR)
+ 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);
- head.h_cc = NOSTR;
- if (replyto == NOSTR) {
- cp = hfield("cc", mp);
- if (cp != NOSTR) {
- np = elide(extract(cp, GCC));
- mapf(np, rcv);
- np = delname(np, myname);
- if (altnames != 0)
- for (ap = altnames; *ap; ap++)
- np = delname(np, *ap);
- head.h_cc = detract(np, 0);
- }
- }
- head.h_bcc = NOSTR;
- mail1(&head);
+ 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)
- char *subj;
+ register char *subj;
{
- char sbuf[10];
- register char *newsubj;
+ char *newsubj;
if (subj == NOSTR)
- return(NOSTR);
- strncpy(sbuf, subj, 3);
- sbuf[3] = 0;
- if (icequal(sbuf, "re:"))
- return(subj);
- newsubj = salloc(strlen(subj) + 6);
- sprintf(newsubj, "Re: %s", subj);
- return(newsubj);
+ 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;
{
}
/*
- * Print the size of each message.
+ * 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;
{
for (ip = msgvec; *ip != NULL; ip++) {
mesg = *ip;
mp = &message[mesg-1];
- printf("%d: %d\n", mesg, msize(mp));
+ 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;
{
char varbuf[BUFSIZ], **ap, **p;
int errs, h, s;
- if (argcount(arglist) == 0) {
+ if (*arglist == NOSTR) {
for (h = 0, s = 1; h < HSHSIZE; h++)
for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
s++;
/*
* Unset a bunch of variable values.
*/
-
+int
unset(arglist)
char **arglist;
{
register struct var *vp, *vp2;
- register char *cp;
int errs, h;
char **ap;
variables[h] = variables[h]->v_link;
vfree(vp2->v_name);
vfree(vp2->v_value);
- cfree(vp2);
+ 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);
- cfree(vp2);
+ free((char *) vp2);
}
return(errs);
}
/*
* Put add users to a group.
*/
-
+int
group(argv)
char **argv;
{
int s;
char **ap, *gname, **p;
- if (argcount(argv) == 0) {
+ if (*argv == NOSTR) {
for (h = 0, s = 1; h < HSHSIZE; h++)
for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
s++;
printgroup(*p);
return(0);
}
- if (argcount(argv) == 1) {
+ if (argv[1] == NOSTR) {
printgroup(*argv);
return(0);
}
* Sort the passed string vecotor into ascending dictionary
* order.
*/
-
+void
sort(list)
char **list;
{
;
if (ap-list < 2)
return;
- qsort(list, ap-list, sizeof *list, diction);
+ qsort(list, ap-list, sizeof(*list), diction);
}
/*
* Do a dictionary order comparison of the arguments from
* qsort.
*/
-
+int
diction(a, b)
- register char **a, **b;
+ const void *a, *b;
{
- return(strcmp(*a, *b));
+ return(strcmp(*(char **)a, *(char **)b));
}
/*
* The do nothing command for comments.
*/
+/*ARGSUSED*/
+int
null(e)
+ int e;
{
- return(0);
+ return 0;
}
/*
- * Print out the current edit file, if we are editing.
- * Otherwise, print the name of the person who's mail
- * we are reading.
+ * Change to another file. With no argument, print information about
+ * the current file.
*/
-
+int
file(argv)
- char **argv;
+ register char **argv;
{
- register char *cp;
- char fname[BUFSIZ];
if (argv[0] == NOSTR) {
newfileinfo();
- return(0);
- }
-
- /*
- * Acker's! Must switch to the new file.
- * We use a funny interpretation --
- * # -- gets the previous file
- * % -- gets the invoker's post office box
- * %user -- gets someone else's post office box
- * & -- gets invoker's mbox file
- * string -- reads the given file
- */
-
- cp = getfilename(argv[0]);
- if (cp == NOSTR)
- return(-1);
- return(setfile(cp, 1));
-}
-
-/*
- * Evaluate the string given as a new mailbox name.
- * Ultimately, we want this to support a number of meta characters.
- * Possibly:
- * % -- for my system mail box
- * %user -- for user's system mail box
- * # -- for previous file
- * & -- get's invoker's mbox file
- * file name -- for any other file
- */
-
-char prevfile[PATHSIZE];
-
-char *
-getfilename(name)
- char *name;
-{
- register char *cp;
- char savename[BUFSIZ];
- char oldmailname[BUFSIZ];
-
- switch (*name) {
- case '%':
- strcpy(prevfile, mailname);
- if (name[1] != 0) {
- strcpy(savename, myname);
- strcpy(oldmailname, mailname);
- strncpy(myname, name+1, PATHSIZE-1);
- myname[PATHSIZE-1] = 0;
- findmail();
- cp = savestr(mailname);
- strcpy(myname, savename);
- strcpy(mailname, oldmailname);
- return(cp);
- }
- strcpy(oldmailname, mailname);
- findmail();
- cp = savestr(mailname);
- strcpy(mailname, oldmailname);
- return(cp);
-
- case '#':
- if (name[1] != 0)
- goto regular;
- if (prevfile[0] == 0) {
- printf("No previous file\n");
- return(NOSTR);
- }
- cp = savestr(prevfile);
- strcpy(prevfile, mailname);
- return(cp);
-
- case '&':
- strcpy(prevfile, mailname);
- if (name[1] == 0)
- return(mbox);
- /* Fall into . . . */
-
- default:
-regular:
- strcpy(prevfile, mailname);
- cp = expand(name);
- return(cp);
+ return 0;
}
+ if (setfile(*argv) < 0)
+ return 1;
+ announce();
+ return 0;
}
/*
* Expand file names like echo
*/
-
+int
echo(argv)
char **argv;
{
for (ap = argv; *ap != NOSTR; ap++) {
cp = *ap;
- if ((cp = expand(cp)) != NOSTR)
- printf("%s ", cp);
+ if ((cp = expand(cp)) != NOSTR) {
+ if (ap != argv)
+ putchar(' ');
+ printf("%s", cp);
+ }
}
- return(0);
+ putchar('\n');
+ return 0;
+}
+
+int
+Respond(msgvec)
+ int *msgvec;
+{
+ if (value("Replyall") == NOSTR)
+ return (_Respond(msgvec));
+ else
+ return (_respond(msgvec));
}
/*
* and not messing around with the To: and Cc: lists as in normal
* reply.
*/
-
-Respond(msgvec)
+int
+_Respond(msgvec)
int msgvec[];
{
struct header head;
struct message *mp;
- register int s, *ap;
- register char *cp, *subject;
+ register int *ap;
+ register char *cp;
- for (s = 0, ap = msgvec; *ap != 0; ap++) {
- mp = &message[*ap - 1];
- dot = mp;
- s += strlen(nameof(mp, 2)) + 1;
- }
- if (s == 0)
- return(0);
- cp = salloc(s + 2);
- head.h_to = cp;
+ head.h_to = NIL;
for (ap = msgvec; *ap != 0; ap++) {
mp = &message[*ap - 1];
- cp = copy(nameof(mp, 2), cp);
- *cp++ = ' ';
+ 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));
}
- *--cp = 0;
+ if (head.h_to == NIL)
+ return 0;
mp = &message[msgvec[0] - 1];
- subject = hfield("subject", mp);
- head.h_seq = 0;
- if (subject == NOSTR)
- subject = hfield("subj", mp);
- head.h_subject = reedit(subject);
- if (subject != NOSTR)
- head.h_seq++;
- head.h_cc = NOSTR;
- head.h_bcc = NOSTR;
- mail1(&head);
- return(0);
+ 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;
{
* Implement 'else'. This is pretty simple -- we just
* flip over the conditional flag.
*/
-
+int
elsecmd()
{
/*
* End of if statement. Just set cond back to anything.
*/
-
+int
endifcmd()
{
/*
* Set the list of alternate names.
*/
+int
alternates(namelist)
char **namelist;
{
return(0);
}
if (altnames != 0)
- cfree((char *) altnames);
- altnames = (char **) calloc(c, sizeof (char *));
+ free((char *) altnames);
+ altnames = (char **) calloc((unsigned) c, sizeof (char *));
for (ap = namelist, ap2 = altnames; *ap; ap++, ap2++) {
- cp = (char *) calloc(strlen(*ap) + 1, sizeof (char));
+ cp = (char *) calloc((unsigned) strlen(*ap) + 1, sizeof (char));
strcpy(cp, *ap);
*ap2 = cp;
}