home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.freefriends.org
/
ftp.freefriends.org.tar
/
ftp.freefriends.org
/
arnold
/
Source
/
mush.rstevens.tar.gz
/
mush.tar
/
command2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-30
|
14KB
|
596 lines
/* @(#)command2.c (c) copyright 1991 (Dan Heller) */
#include "mush.h"
/*
* Note that all of the routines in here act upon and return 0 or -1.
* if -1, then the main loop will clear message lists.
*/
/* This is the bottom half of commands.c */
/*
* Do an ls from the system.
* Read from a popen and use wprint in case the tool does this command.
* The folders command uses this command.
*/
ls(x, argv)
int x;
char **argv;
{
register char *p, *tmp;
char buf[128];
register FILE *pp;
if (*++argv && !strcmp(*argv, "-?"))
return help(0, "ls", cmd_help);
p = buf + strlen(sprintf(buf, "%s -C", LS_COMMAND));
for ( ; *argv; ++argv) {
x = 0;
if (**argv != '-')
tmp = getpath(*argv, &x);
else
tmp = *argv;
if (x == -1) {
wprint("%s: %s\n", *argv, tmp);
return -1;
}
*p++ = ' ';
p += Strcpy(p, tmp);
}
if (!(pp = popen(buf, "r"))) {
error(buf);
return -1;
}
(void) do_pager(NULL, TRUE);
while (fgets(buf, 127, pp) && do_pager(buf, FALSE) != EOF)
;
(void) pclose(pp);
(void) do_pager(NULL, FALSE);
return 0;
}
/*ARGSUSED*/
sh(un_used, argv)
int un_used;
char **argv;
{
register char *p;
char buf[BUFSIZ];
if (*++argv && !strcmp(*argv, "-?"))
return help(0, "shell", cmd_help);
if (!(p = do_set(set_options, "shell")))
p = DEF_SHELL;
if (!*argv)
if (istool) {
print("You can't run an interactive shell from tool mode (yet).");
return -1;
} else
(void) strcpy(buf, p);
else
(void) argv_to_string(buf, argv);
if (!istool)
echo_on();
(void) system(buf);
if (!istool)
echo_off();
return 0;
}
#ifdef SIGSTOP
stop(argc, argv)
int argc;
char **argv;
{
if (istool)
print("Not a tool-based option.");
if (argc && *++argv && !strcmp(*argv, "-?"))
return help(0, "stop", cmd_help);
if (kill(getpid(), SIGTSTP) == -1)
error("couldn't stop myself");
return 0;
}
#endif /* SIGSTOP */
extern char **environ;
static int spaces = 0;
Setenv(i, argv)
int i;
char **argv;
{
char *newstr;
if (i < 2)
return Printenv(i, argv);
else if (i > 3 || !strcmp(argv[1], "-?"))
return help(0, "setenv", cmd_help);
if (i == 3) {
if (newstr = malloc((unsigned) (strlen(argv[1]) + strlen(argv[2]) + 2)))
(void) sprintf(newstr, "%s=%s", argv[1], argv[2]);
} else {
if (newstr = malloc((unsigned)(strlen(argv[1]) + 2)))
(void) sprintf(newstr, "%s=", argv[1]);
}
if (!newstr) {
error("setenv: out of memory");
return -1;
}
(void) Unsetenv(2, argv);
for (i = 0; environ[i]; i++);
if (!spaces) {
char **new_environ =
(char **)malloc((unsigned) ((i+2) * sizeof(char *)));
/* add 1 for the new item, and 1 for null-termination */
if (!new_environ) {
xfree(newstr);
return -1;
}
spaces = 1;
for (i = 0; new_environ[i] = environ[i]; i++);
xfree((char *) environ);
environ = new_environ;
}
environ[i] = newstr;
environ[i+1] = NULL;
spaces--;
return 0;
}
Unsetenv(n, argv)
int n;
char **argv;
{
static int new;
char **envp, **last;
if (n != 2 || !strcmp(argv[1], "-?"))
return help(0, "unsetenv", cmd_help);
n = strlen(argv[1]);
for (last = environ; *last; last++);
/* Allocate a copy of the environment so we can free() strings we unset */
if (new == 0) {
if (!(envp = (char **)calloc((last - environ) + 1, sizeof(char *)))) {
error("Unsetenv: out of memory");
return -1;
}
while (environ[new]) {
envp[new] = savestr(environ[new]);
if (!envp[new++]) {
error("Unsetenv: out of memory");
free_vec(envp);
new = 0;
return -1;
}
}
environ = envp;
last = &envp[new];
new = 1;
}
if (last == environ) /* Empty environment? */
return 0;
last--;
for (envp = environ; envp <= last; envp++) {
if (strncmp(argv[1], *envp, n) == 0 && (*envp)[n] == '=') {
xfree(*envp);
*envp = *last;
*last-- = NULL;
spaces++;
}
}
return 0;
}
Printenv(argc, argv)
int argc;
char **argv;
{
char **e;
if (argv && argv[1] && !strcmp(argv[1], "-?"))
return help(0, "printenv", cmd_help);
for (e = environ; *e; e++)
if (argc < 2 || !strncmp(*e, argv[1], strlen(argv[1])))
wprint("%s\n", *e);
return 0;
}
/*
* internal stty call to allow the user to change his tty character
* settings. sorry, no way to change cbreak/echo modes. Save echo_flg
* so that execute() won't reset it.
*/
/*ARGSUSED*/
my_stty(un_used, argv)
int un_used;
char **argv;
{
u_long save_echo = ison(glob_flags, ECHO_FLAG);
if (istool)
return 0;
if (argv && argv[1] && !strcmp(argv[1], "-?"))
return help(0, "stty", cmd_help);
echo_on();
turnon(glob_flags, ECHO_FLAG);
execute(argv);
if (save_echo)
turnon(glob_flags, ECHO_FLAG);
else
turnoff(glob_flags, ECHO_FLAG);
savetty();
#ifdef TIOCGLTC
if (ioctl(0, TIOCGLTC, <chars))
error("TIOCGLTC");
#endif /* TIOCGLTC */
echo_off();
return 0;
}
/*
* Edit a message...
*/
edit_msg(i, argv, list)
int i;
char *argv[], list[];
{
int edited = 0;
char buf[MAXPATHLEN], *b, *dir, **edit_cmd, *editor, *mktemp();
u_long flags = 0L;
char *cmd = *argv;
FILE *fp;
if (istool)
return 0;
if (*++argv && !strcmp(*argv, "-?"))
return help(0, "edit_msg", cmd_help);
if (ison(glob_flags, READ_ONLY)) {
print("\"%s\" is read-only.\n", mailfile);
return -1;
}
if (get_msg_list(argv, list) == -1)
return -1;
if (!(editor = do_set(set_options,
(*cmd == 'v')? "visual" : "editor")) || !*editor)
editor = DEF_EDITOR;
for (i = 0; i < msg_cnt; i++) {
if (!msg_bit(list, i))
continue;
if (edited) {
print("Edit message %d [y/n/q]? ", i+1);
if (Getstr(buf, sizeof (buf), 0) < 0 || lower(buf[0]) == 'q')
return 0;
if (buf[0] && buf[0] != 'y')
continue;
}
b = buf + Strcpy(buf, editor);
*b++ = ' ';
/* getdir() uses the home directory if no tmpdir */
if (!(dir = getdir(do_set(set_options, "tmpdir"))))
alted:
dir = ALTERNATE_HOME;
(void) mktemp(sprintf(b, "%s/.msgXXXXXXX", dir));
if (!(fp = mask_fopen(b, "w+"))) {
if (strcmp(dir, ALTERNATE_HOME))
goto alted;
error("can't create %s", b);
return -1;
}
wprint("editing message %d ...", i+1);
/* copy message into file making sure all headers exist. */
turnon(flags, UPDATE_STATUS);
#ifdef MMDF
turnon(flags, NO_SEPARATOR);
#endif /* MMDF */
wprint("(%d lines)\n", copy_msg(i, fp, flags, NULL));
if (edit_cmd = mk_argv(buf, &edited, FALSE)) {
print("Starting \"%s\"...\n", buf);
(void) fclose(fp);
turnon(glob_flags, IS_GETTING);
execute(edit_cmd);
turnoff(glob_flags, IS_GETTING);
free_vec(edit_cmd);
if (load_folder(b, FALSE, (char *)i) > 0) {
(void) unlink(b);
edited = 1;
}
set_isread(i); /* if you edit it, you read it, right? */
}
}
return 0;
}
/*
* Pipe a message list to a unix command. This function is hacked together
* from bits of readmsg, above, and other bits of display_msg (misc.c).
*/
pipe_msg(x, argv, list)
int x;
char **argv, list[];
{
char *p = x ? *argv : NULL;
char buf[256], *pattern = NULL;
u_long flg = 0L;
extern FILE *ed_fp;
int show_deleted = !!do_set(set_options, "show_deleted");
/* Increment argv only if argv[0] is the mush command "pipe" */
if (x && p && (!strcmp(p, "pipe") || !strcmp(p, "Pipe"))) {
if (p && *p == 'P')
turnon(flg, NO_HEADER);
while (x && *++argv && **argv == '-')
if (!strcmp(*argv, "-?"))
return help(0, "pipe_msg", cmd_help);
else if (!strcmp(*argv, "-p") && !(pattern = *++argv)) {
print("Specify a pattern with -p\n");
return -1;
}
}
if (!msg_cnt) {
print("No messages.\n");
return -1;
}
if (x && (x = get_msg_list(argv, list)) == -1)
return -1;
argv += x;
if (!*argv) {
turnon(flg, NO_HEADER);
/* The constant strings must be constants because user's
* $SHELL might not be appropriate since "sh" scripts are
* usually sent. User can always (easily) override.
*/
(void) strcpy(buf, "/bin/sh");
if (!pattern)
pattern = "#!";
} else
(void) argv_to_string(buf, argv);
if (!buf[0]) {
print("Must specify a legitimate command or shell.\n");
return -1;
}
current_msg = 0;
if (!chk_option("alwaysignore", "pipe"))
turnon(flg, NO_IGNORE);
#ifdef MMDF
turnon(flg, NO_SEPARATOR);
#endif /* MMDF */
(void) do_pager(buf, -1); /* start pager -- see do_pager() about "-1" */
turnoff(glob_flags, WAS_INTR); /* if command interrupts, mush gets it */
for (x = 0; x < msg_cnt && isoff(glob_flags, WAS_INTR); x++)
if (msg_bit(list, x)) {
current_msg = x;
if (!show_deleted && ison(msg[x].m_flags, DELETE)) {
print("Message %d deleted; ", x+1);
if (iscurses)
print_more("skipping it.");
else
print("skipping it.\n");
continue;
}
set_isread(x);
if (copy_msg(x, NULL_FILE, flg, pattern) == 0)
print("No lines sent to %s!\n", buf);
}
(void) do_pager(NULL, FALSE); /* end pager */
return 0;
}
/* echo the arguments. return 0 or -1 if -h given and there are no msgs. */
do_echo(n, argv)
int n;
char **argv;
{
char buf[BUFSIZ], c;
int no_return = 0, comp_hdr = 0, as_prompt = 0;
while (n >= 0 && argv && *++argv && **argv == '-') {
n = 1;
while (n > 0 && (c = argv[0][n++]))
switch(c) {
case 'n': no_return++;
when 'h': comp_hdr++;
when 'p': as_prompt++;
when '?': return help(0, "echo", cmd_help);
otherwise: n = -1; break; /* Just echo whatever it was */
}
}
if (comp_hdr && as_prompt) {
print("-h and -p cannot be used together.\n");
return -1;
}
(void) argv_to_string(buf, argv);
if (comp_hdr) {
if (!msg_cnt) {
print("No messages.\n");
return -1;
}
/* there may be a %-sign, so use %s to print */
print("%s", format_hdr(current_msg, buf, FALSE)+9);
} else if (as_prompt) {
print("%s", format_prompt(current_msg, buf)); /* may be a %-sign */
} else
print("%s", buf); /* there may be a %-sign in "buf" */
if (!no_return)
print_more("\n");
return 0;
}
eval_cmd (argc, argv, list)
int argc;
char *argv[], list[];
{
int status = -1;
u_long save_is_pipe;
char **newav, buf[BUFSIZ];
int comp_hdr = 0, as_prompt = 0, as_macro = 0;
while (argv && *++argv && **argv == '-') {
int c, n = 1;
while (c = argv[0][n++])
switch(c) {
case 'h': comp_hdr++;
when 'p': as_prompt++;
when 'm': as_macro++;
otherwise: return help(0, "eval", cmd_help);
}
}
if (comp_hdr && as_prompt) {
print("-h and -p cannot be used together.\n");
return -1;
}
(void) argv_to_string(buf, argv);
if (as_macro) {
m_xlate(buf);
mac_queue(buf);
return 0;
}
newav = make_command(buf, TRPL_NULL, &argc);
if (comp_hdr) {
if (!msg_cnt) {
print("No messages.\n");
return -1;
}
/* This is inefficient, but the only way to preserve
* imbedded quotes, tabs, etc. in format expansions.
*/
for (argv = newav; argv && *argv; argv++) {
/* Don't mess with one-character strings */
if (argv[0][1]) {
char *format = *argv;
*argv = savestr(format_hdr(current_msg, format, FALSE)+9);
Debug("expanding (%s) to (%s)\n", format, *argv);
xfree(format);
}
}
} else if (as_prompt) {
for (argv = newav; argv && *argv; argv++) {
/* Don't mess with one-character strings */
if (argv[0][1]) {
char *tmp = *argv;
*argv = savestr(format_prompt(current_msg, tmp));
Debug("expanding (%s) to (%s)\n", tmp, *argv);
xfree(tmp);
}
}
}
/* Can't use cmd_line() because we want DO_PIPE and IS_PIPE
* to remain on -- cmd_line() turns both of them off
*/
if (newav) {
save_is_pipe = ison(glob_flags, IS_PIPE);
status = do_command(argc, newav, list);
if (save_is_pipe)
turnon(glob_flags, IS_PIPE);
}
return status;
}
await(argc, argv, list)
int argc;
char *argv[], list[];
{
int done = 0, snooze = 30, last_cnt = msg_cnt;
if (argc && *++argv) {
if (!strcmp(*argv, "-?"))
return help(0, "await", cmd_help);
else if (!strcmp(*argv, "-T")) {
if (*++argv && isdigit(**argv) && **argv > '0') {
snooze = atoi(*argv);
} else {
print("await: integer greater than 0 required for -T\n");
return -1;
}
}
}
Debug("snoozing %d\n", snooze);
do {
if (!(done = check_new_mail()))
sleep((unsigned) snooze);
} while (!done);
/* Known to be safe to pass NULL to chk_two_lists() */
if (!chk_option("quiet", "await"))
bell();
while (last_cnt < msg_cnt) {
set_msg_bit(list, last_cnt);
++last_cnt;
}
return 0;
}
mark_msg(x, argv, list)
int x;
char **argv, list[];
{
int i, set_priority = 0;
int unmark = argv && argv[0] && argv[0][0] == 'u';
if (argv && *++argv && !strcmp(*argv, "-?"))
return help(0, "mark", cmd_help);
/* command must be "mark [ -[A|B|C|D|E] ] [msg_list]" */
if (!unmark && argv && *argv && **argv == '-') {
if (!argv[0][1])
set_priority = -1; /* special case for clearing priority */
else if ((set_priority = (upper(argv[0][1]) - 'A' + 1)) < 1 ||
set_priority > MAX_PRIORITY) {
print("mark: priority -A through -%c required (- to clear)\n",
MAX_PRIORITY + 'A');
return -1;
}
++argv;
}
if (x && (x = get_msg_list(argv, list)) == -1)
return -1;
argv += x;
/* if extraneous args exist or the priority was misspecified... */
if (argv[0]) {
print("Unknown arg: %s. mark -? for help.\n", *argv);
return -1;
}
for (x = 0; x < msg_cnt; x++)
if (msg_bit(list, x)) {
if (set_priority)
/* could be setting priority or clearing all priorities */
for (i = 1; i <= MAX_PRIORITY; i++)
turnoff(msg[x].m_flags, M_PRIORITY(i));
if (unmark)
turnoff(msg[x].m_flags, M_PRIORITY(0));
else if (set_priority > 0) {
turnon(msg[x].m_flags, M_PRIORITY(set_priority)|DO_UPDATE);
turnon(glob_flags, DO_UPDATE);
} else if (set_priority == 0)
turnon(msg[x].m_flags, M_PRIORITY(0));
}
if (istool > 1)
(void) do_hdrs(0, DUBL_NULL, NULL);
return 0;
}