mencmds.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Copyright (c) 1985 AT&T
* All Rights Reserved
*/
#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.26 */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h> /* EFT abs k16 */
#include "typetab.h"
#include "wish.h"
#include "terror.h"
#include "procdefs.h"
#include "eval.h"
#include "ctl.h"
#include "moremacros.h"
#include "message.h"
#include "sizes.h"
/*
* Globals used in eval() ...
*/
extern int EV_retcode;
extern int EV_backquotes;
extern int Lasttok;
extern int Vflag;
int
cmd_setodi(argc, argv, instr, outstr, errstr)
int argc;
char *argv[];
IOSTRUCT *instr;
IOSTRUCT *outstr;
IOSTRUCT *errstr;
{
char *path;
char *key;
char *value;
struct ott_entry *ott;
struct ott_entry *path_to_ott();
switch (argc) {
case 1:
case 2:
mess_temp("setodi: not enough arguments");
return(FAIL);
case 3:
path = argv[1];
key = argv[2];
value = io_string(instr);
break;
default:
mess_temp("setodi: extra args ignored");
case 4:
path = argv[1];
key = argv[2];
value = strsave(argv[3]);
break;
}
if ((ott = path_to_ott(path)) != NULL) {
ott_lock_dsk(path);
odi_putkey(ott, key, value);
ott_dirty();
ott_synch(FALSE);
}
if (value)
free(value);
return(SUCCESS);
}
int
cmd_getodi(argc, argv, instr, outstr, errstr)
int argc;
char *argv[];
IOSTRUCT *instr;
IOSTRUCT *outstr;
IOSTRUCT *errstr;
{
char *path;
char *key;
char *value;
struct ott_entry *ott;
struct ott_entry *path_to_ott();
char *odi_getkey();
switch (argc) {
case 1:
case 2:
mess_temp("putodi: not enough args");
return(FAIL);
default:
mess_temp("putodi: extra args ignored");
case 3:
path = argv[1];
key = argv[2];
break;
}
if ((ott = path_to_ott(path)) == NULL)
return(FAIL);
if (value = odi_getkey(ott, key)) {
putastr(value, outstr);
return(SUCCESS);
} else
return(FAIL);
}
int
cmd_run(argc, argv, instr, outstr, errstr)
int argc;
char *argv[];
IOSTRUCT *instr;
IOSTRUCT *outstr;
IOSTRUCT *errstr;
{
register int i;
int procflags = 0;
char *title = NULL;
bool silent = FALSE;
for (i = 1; argv[i][0] == '-'; i++) {
switch (argv[i][1]) {
case 's':
silent = TRUE;
break;
case 'n':
procflags = PR_NOPROMPT;
break;
case 'e':
procflags = PR_ERRPROMPT;
break;
case 't':
title = &argv[i][2];
break;
default:
break;
}
}
if (silent)
return waitspawn(spawnv(argv[i], argv + i));
else
return proc_openv(procflags, title, NULL, argv+i);
}
int
cmd_unset(argc, argv, instr, outstr, errstr)
int argc;
char *argv[];
IOSTRUCT *instr;
IOSTRUCT *outstr;
IOSTRUCT *errstr;
{
register int i;
char *var = NULL;
char *file = NULL;
char path[PATHSIZ];
char whichenv;
extern char *Home;
char *strchr();
char *io_string();
whichenv = '\0';
for (i = 1; argv[i]; i++) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'l':
whichenv = argv[i][1];
break;
case 'f':
file = argv[i] + 2;
break;
}
}
else {
var = argv[i];
if (whichenv == 'l')
delAltenv(var);
else {
if (!file) {
strcpy(path, Home);
strcat(path, "/pref/.environ");
file = path;
}
chgenv(file, var, NULL);
}
file = NULL;
whichenv = '\0';
}
}
return SUCCESS;
}
int
cmd_set(argc, argv, instr, outstr, errstr)
int argc;
char *argv[];
IOSTRUCT *instr;
IOSTRUCT *outstr;
IOSTRUCT *errstr;
{
register int i;
char *val = NULL;
char *var = NULL;
char *file = NULL;
char path[PATHSIZ];
char buf[BUFSIZ];
char whichenv;
char *envbuf;
extern char *Home;
char *strchr();
char *io_string();
int dofree, amt, maxamt;
whichenv = '\0';
for (i = 1; argv[i]; i++) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'l':
case 'e':
whichenv = argv[i][1];
break;
case 'f':
file = argv[i] + 2;
break;
}
}
else {
dofree = 0;
if (!(var = strchr(argv[i], '='))) {
maxamt = BUFSIZ - strlen(argv[i]) - 2;
val = io_string(instr);
if ((amt = strlen(val)) > maxamt) {
/*
* Value is greater than 1K so malloc
* enough space to hold it.
*/
maxamt = amt + strlen(argv[i]) + 2;
if ((envbuf = (char *) malloc(maxamt)) == NULL)
fatal(NOMEM, nil);
dofree++;
}
else {
/*
* ... otherwise, use static 1K buffer
*/
envbuf = buf;
}
strcpy(envbuf, argv[i]);
strcat(envbuf, "=");
strncat(envbuf, val, maxamt);
var = envbuf;
free(val);
val = &var[strlen(var) - 1];
if (*val == '\n')
*val = '\0';
}
else
var = argv[i];
if (whichenv == 'l')
putAltenv(var);
else if (whichenv == 'e')
putenv(strsave(var));
else {
if (!file) {
strcpy(path, Home);
strcat(path, "/pref/.environ");
file = path;
}
val = strchr(var, '=');
*val++ = '\0';
chgenv(file, var, val);
}
if (dofree) {
free(envbuf);
envbuf = NULL;
}
file = NULL;
whichenv = '\0';
}
}
return SUCCESS;
}
/* types of messages (temporary, permanent, frame permanent) */
#define MTEMP 0x1
#define MPERM 0x2
#define MFRAME 0x4
int
cmd_message(argc, argv, instr, outstr, errstr)
int argc;
char *argv[];
IOSTRUCT *instr;
IOSTRUCT *outstr;
IOSTRUCT *errstr;
{
char msg[MESSIZ];
register char *amessage;
register int i;
register int messtype;
bool output = FALSE;
bool work = FALSE;
bool bell = FALSE;
bool dofree;
int num;
char *ptr;
char *io_string();
messtype = 0;
amessage = NULL;
msg[0] = msg[MESSIZ - 1] = '\0';
for (i = 1; argv[i]; i++) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'p':
messtype = MPERM;
break;
case 't':
messtype = MTEMP;
break;
case 'f':
messtype = MFRAME;
break;
case 'o':
output = TRUE;
break;
case 'w':
work = TRUE;
break;
case 'b':
bell = TRUE;
if((ptr=strpbrk(argv[i],"0123456789")) || (ptr=strpbrk(argv[i + 1],"0123456789"))) {
num = atoi(ptr);
i++;
}
else
num=1;
break;
default:
break;
}
} else {
amessage = msg;
strncat(msg, argv[i], MESSIZ - 1 - strlen(msg));
strncat(msg, " ", MESSIZ - 1 - strlen(msg));
}
}
if (amessage == NULL) {
amessage = io_string(instr);
dofree = TRUE;
} else
dofree = FALSE;
if (messtype & MPERM) {
mess_perm(amessage);
mess_flash(amessage);
}
else if (messtype & MFRAME) {
mess_frame(amessage);
mess_flash(amessage);
ar_ctl(ar_get_current(), CTSETMSG, TRUE, NULL, NULL, NULL, NULL, NULL);
}
else { /* temporary message assumed */
mess_temp(amessage);
mess_flash(amessage);
}
if (output)
putastr(amessage, outstr);
if (dofree)
free(amessage);
if (work)
working(TRUE);
/* les */
else
doupdate();
if (bell) {
for(i = num; i > 0; i--)
beep();
}
/*
flush_output();
*/
return SUCCESS;
}
int
cmd_indicator(argc, argv, instr, outstr, errstr)
int argc;
char *argv[];
IOSTRUCT *instr;
IOSTRUCT *outstr;
IOSTRUCT *errstr;
{
char msg[MESSIZ];
register char *amessage;
register int i, mescol, meslength;
bool output = FALSE;
bool work = FALSE;
bool bell = FALSE;
bool dofree;
int num;
char *ptr;
char *io_string();
mescol = 0;
meslength = MESSIZ;
amessage = NULL;
msg[0] = msg[MESSIZ - 1] = '\0';
for (i = 1; argv[i]; i++) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'c':
mescol = atoi(argv[i + 1]);
i++;
break;
case 'l':
meslength = atoi(argv[i + 1]);
i++;
break;
case 'o':
output = TRUE;
break;
case 'w':
work = TRUE;
break;
case 'b':
bell = TRUE;
if((ptr=strpbrk(argv[i],"0123456789")) || (ptr=strpbrk(argv[i + 1],"0123456789"))) {
num = atoi(ptr);
i++;
}
else
num=1;
break;
default:
break;
}
} else {
amessage = msg;
strncat(msg, argv[i], meslength - 1 - strlen(msg));
strncat(msg, " ", meslength - 1 - strlen(msg));
}
}
if (amessage == NULL) {
amessage = io_string(instr);
dofree = TRUE;
} else
dofree = FALSE;
indicator(amessage, mescol);
if (output)
putastr(amessage, outstr);
if (dofree)
free(amessage);
if (work)
working(TRUE);
else
doupdate();
if (bell) {
for(i = num; i > 0; i--)
beep();
}
return SUCCESS;
}
#define MAX_PATTERNS 32
/*
* Usage: regex [-v string] [-e] pattern [template] [pattern [template] ...]
*
* The first form takes a string and matches it against patterns until
* there is a match. Patterns are regular expression as described in
* regcmp(3X). When a match is found, the corresponding template is
* returned in the output stream. Templates may be arbitrary strings,
* but if the string $m0, $m1, ..., $m9 appear in the string, then they
* will be expanded to the corresponding pattern that matched within
* (...)$0 through (...)$9 parts of the pattern.
* For example:
* regex "0123456789" '.{2}(.{3})$0' 'hi $m0'
* would return the string: 'hi 234'.
* The default template is '$m0$m1$m2$m3$m4$m5$m6$m7$m8$m9'.
*
* The -v option causes string to be parsed instead of stdin
*
* The -e option causes the resulting template to be evaluated
*/
cmd_regex(argc, argv, instr, outstr, errstr)
int argc;
char *argv[];
IOSTRUCT *instr;
IOSTRUCT *outstr;
IOSTRUCT *errstr;
{
IOSTRUCT *myoutstr, *tmpoutstr;
register char *p;
char *ptr, *value;
char buf[BUFSIZ];
char ret[10][BUFSIZ];
char *pattern[MAX_PATTERNS];
char *template[MAX_PATTERNS];
static char deftemplate[] = "$m0$m1$m2$m3$m4$m5$m6$m7$m8$m9";
register int i;
register int j;
register int numpatterns, execflag;
register bool matches;
char *regex();
char *regcmp();
char *getastr();
int savecode, savetok, savequotes;
value = NULL;
execflag = FALSE;
for (i = 1; argv[i][0] == '-'; i++) {
switch (argv[i][1]) {
case 'e': /* evaluate the matched template */
execflag = TRUE;
break;
case 'v': /* from a variable */
if (argv[1][2])
value = &argv[1][2];
else
value = argv[++i];
break;
default:
break;
}
}
if (execflag) { /* generate an intermediate IO chanel */
tmpoutstr = io_open(EV_USE_STRING, NULL);
myoutstr = tmpoutstr;
}
else
myoutstr = outstr; /* use the requested IO channel */
numpatterns = 0;
for ( ; i < argc; i += 2) {
if ((pattern[numpatterns] = regcmp(argv[i], NULL)) == NULL)
warn(MUNGED, "regex pattern");
if (argv[i + 1])
template[numpatterns++] = argv[i + 1];
else
template[numpatterns++] = deftemplate;
}
matches = FALSE;
for ( ; ; ) {
if (value)
ptr = value;
else if (getastr(buf, BUFSIZ, instr)) {
ptr = buf;
if (buf[i = strlen(buf) - 1] == '\n')
buf[i] = '\0';
}
else
break;
for (i = 0; i < numpatterns; i++) {
if (pattern[i] == NULL)
continue;
for (j = 0; j < 10; j++)
ret[j][0] = '\0';
if (regex(pattern[i], ptr, ret[0], ret[1], ret[2],
ret[3], ret[4], ret[5], ret[6],
ret[7], ret[8], ret[9])) {
matches = TRUE;
for (p = template[i]; *p; p++) {
if (*p == '$' && p[1] == 'm' && isdigit(p[2])) {
putastr(ret[p[2] - '0'], myoutstr);
p += 2;
}
else
putac(*p, myoutstr);
}
if (strcmp(template[i], deftemplate) != 0)
putac('\n', myoutstr);
break;
}
}
if (value)
break;
}
if (execflag == TRUE) { /* evaluate the matched template */
/*
* Save/restore globals used in eval() before/after
* making a recursive call to eval() ... this SHOULD
* change in the future and should not be necessary
*/
savecode = EV_retcode;
savequotes = EV_backquotes;
savetok = Lasttok;
io_seek(myoutstr, 0);
while (eval(myoutstr, outstr, EV_TOKEN | EV_USE_STRING))
putac(' ', outstr);
io_close(myoutstr);
EV_retcode = savecode;
EV_backquotes = savequotes;
Lasttok = savetok;
}
for (i = 0; i < numpatterns; i++)
if (pattern[i])
free(pattern[i]);
return matches ? SUCCESS : FAIL;
}
int
cmd_getlist(argc, argv, instr, outstr, errstr)
int argc;
char *argv[];
IOSTRUCT *instr, *outstr, *errstr;
{
register int i, numitems, pending;
struct actrec *cur_ar;
register char *delimiter;
char *itemptr;
if (argc == 1)
delimiter = "\n";
else
delimiter = argv[1];
cur_ar = (struct actrec *) ar_get_current();
if ((numitems = ar_ctl(cur_ar, CTGETSIZ, NULL, NULL, NULL, NULL, NULL, NULL)) == FAIL) {
putac('\0', outstr);
return(FAIL);
}
for (i = 0, pending = 0; i < numitems; i++) {
ar_ctl(cur_ar, CTGETLIST, i, &itemptr, NULL, NULL, NULL, NULL);
if (itemptr != NULL) {
if (pending++)
putastr(delimiter, outstr);
putastr(itemptr, outstr);
}
}
putac('\0', outstr);
return(SUCCESS);
}
int
cmd_pathconv(argc, argv, instr, outstr, errstr)
int argc;
char *argv[];
IOSTRUCT *instr, *outstr, *errstr;
{
register char *p;
register char *pre;
register char *input;
register int i;
register int n;
register int width;
bool fullpath;
bool show_max;
bool freeit;
char *io_string();
char *path_to_full();
char *path_to_title();
fullpath = TRUE;
freeit = FALSE;
show_max = FALSE;
pre = input = NULL;
width = MAX_TITLE;
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'v':
if (argv[i][2])
input = argv[i] + 2;
else if ((input = argv[++i]) == NULL) {
error(MISSING, "arg to pathconv");
i--;
}
break;
case 'l':
show_max = TRUE;
break;
case 'f':
fullpath = TRUE;
break;
case 't':
fullpath = FALSE;
break;
case 'n':
if (argv[i][2])
width = atoi(argv[i] + 2);
else if ((width = atoi(argv[++i])) <= 0) {
error(MISSING, "arg to pathconv");
i--;
width = MAX_TITLE;
}
break;
default:
error(MUNGED, "bad -arg to pathconv");
break;
}
}
else
pre = argv[i];
}
if (!input) {
/* io_string was returning the input with tabs and newlines
and therefore input to path_to_full was not expanding the
alias. The following two lines will truncate the white space
and newlines from input. -- added 7/89 by njp. */
n = strcspn( input = io_string(instr), " \t\n");
input[n]= '\0';
freeit = TRUE;
}
if (input && *input && *input != ' ')
if (fullpath) {
putastr(p = path_to_full(input), outstr);
free(p);
}
else {
if ( show_max )
putastr(bsd_path_to_title(input, Vflag?42:width), outstr);
else
putastr(path_to_title(input, pre, Vflag?42:width), outstr);
}
if (freeit)
free(input);
return SUCCESS;
}
cmd_setcolor(argc, argv, instr, outstr, errstr)
int argc;
char *argv[];
IOSTRUCT *instr;
IOSTRUCT *outstr;
IOSTRUCT *errstr;
{
if (argc != 5)
return(FAIL);
if (setcolor(argv[1], atoi(argv[2]), atoi(argv[3]), atoi(argv[4]))) {
putastr(argv[1], outstr);
return(SUCCESS);
}
else {
putastr("", outstr);
return(FAIL);
}
}