2000-04-15 01:46:11 +04:00
|
|
|
/* $NetBSD: run.c,v 1.30 2000/04/14 21:46:11 thorpej Exp $ */
|
1997-09-27 03:02:53 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright 1997 Piermont Information Systems Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Written by Philip A. Nelson for Piermont Information Systems Inc.
|
|
|
|
*
|
|
|
|
* 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:
|
1999-06-20 10:08:13 +04:00
|
|
|
* This product includes software developed for the NetBSD Project by
|
1997-09-27 03:02:53 +04:00
|
|
|
* Piermont Information Systems Inc.
|
|
|
|
* 4. The name of Piermont Information Systems Inc. may not be used to endorse
|
|
|
|
* or promote products derived from this software without specific prior
|
|
|
|
* written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``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 PIERMONT INFORMATION SYSTEMS INC. 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* run.c -- routines to interact with other programs. */
|
|
|
|
|
1999-01-21 11:02:17 +03:00
|
|
|
/* XXX write return codes ignored. XXX */
|
|
|
|
|
|
|
|
#include <errno.h>
|
1997-09-27 03:02:53 +04:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdlib.h>
|
1999-01-21 11:02:17 +03:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <curses.h>
|
|
|
|
#include <termios.h>
|
|
|
|
#include <util.h>
|
|
|
|
#include <err.h>
|
|
|
|
#include <sys/ioctl.h>
|
1997-09-27 03:02:53 +04:00
|
|
|
#include <sys/types.h>
|
1999-01-21 11:02:17 +03:00
|
|
|
#include <sys/wait.h>
|
1997-09-27 03:02:53 +04:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include "defs.h"
|
|
|
|
|
1999-01-21 11:02:17 +03:00
|
|
|
#include "menu_defs.h"
|
1997-11-02 06:45:27 +03:00
|
|
|
#include "msg_defs.h"
|
|
|
|
|
1999-01-21 11:02:17 +03:00
|
|
|
#define MAXBUF 256
|
|
|
|
|
1997-09-27 03:02:53 +04:00
|
|
|
#ifdef DEBUG
|
1997-09-27 04:09:22 +04:00
|
|
|
#define Xsystem(y) printf ("%s\n", y), 0
|
1997-09-27 03:02:53 +04:00
|
|
|
#else
|
|
|
|
#define Xsystem(y) system(y)
|
|
|
|
#endif
|
|
|
|
|
1997-11-02 06:45:27 +03:00
|
|
|
/*
|
|
|
|
* local prototypes
|
|
|
|
*/
|
1999-07-05 01:32:48 +04:00
|
|
|
char* va_prog_cmdstr __P((const char *cmd, va_list ap));
|
1999-01-21 11:02:17 +03:00
|
|
|
int launch_subwin __P((WINDOW *actionwin, char **args, struct winsize win, int display));
|
|
|
|
int log_flip __P((void));
|
|
|
|
int script_flip __P((void));
|
1997-11-02 06:45:27 +03:00
|
|
|
|
1997-09-27 03:02:53 +04:00
|
|
|
#define BUFSIZE 4096
|
|
|
|
|
1999-01-21 11:02:17 +03:00
|
|
|
char log_text[2][30] = {"Logging: Off", "Scripting: Off"};
|
|
|
|
|
|
|
|
menu_ent logmenu [2] = {
|
|
|
|
{ log_text[0], OPT_NOMENU, 0, log_flip},
|
|
|
|
{ log_text[1], OPT_NOMENU, 0, script_flip} };
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
do_logging(void)
|
|
|
|
{
|
|
|
|
int menu_no;
|
|
|
|
|
1999-06-21 00:26:42 +04:00
|
|
|
menu_no = new_menu ("Logging Functions", logmenu, 2, -1, 12,
|
|
|
|
0, 20, MC_SCROLL, NULL, NULL, "Pick an option to turn on or off.\n");
|
1999-01-21 11:02:17 +03:00
|
|
|
|
|
|
|
if (menu_no < 0) {
|
|
|
|
(void)fprintf(stderr, "Dynamic menu creation failed.\n");
|
|
|
|
if (logging)
|
|
|
|
(void)fprintf(log, "Dynamic menu creation failed.\n");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
process_menu(menu_no);
|
|
|
|
free_menu(menu_no);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
log_flip(void)
|
|
|
|
{
|
|
|
|
time_t tloc;
|
|
|
|
|
|
|
|
(void)time(&tloc);
|
|
|
|
if (logging == 1) {
|
|
|
|
sprintf(log_text[0], "Logging: Off");
|
|
|
|
logging = 0;
|
|
|
|
fprintf(log, "Log ended at: %s\n", asctime(localtime(&tloc)));
|
|
|
|
fflush(log);
|
|
|
|
fclose(log);
|
|
|
|
} else {
|
|
|
|
log = fopen("sysinst.log", "a");
|
2000-01-07 05:02:05 +03:00
|
|
|
if (log != NULL) {
|
|
|
|
sprintf(log_text[0], "Logging: On");
|
|
|
|
logging = 1;
|
|
|
|
fprintf(log, "Log started at: %s\n", asctime(localtime(&tloc)));
|
|
|
|
fflush(log);
|
|
|
|
} else {
|
|
|
|
msg_display(MSG_openfail, "log file", strerror(errno));
|
|
|
|
}
|
1999-01-21 11:02:17 +03:00
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
script_flip(void)
|
|
|
|
{
|
|
|
|
time_t tloc;
|
|
|
|
|
|
|
|
(void)time(&tloc);
|
|
|
|
if (scripting == 1) {
|
|
|
|
sprintf(log_text[1], "Scripting: Off");
|
|
|
|
scripting = 0;
|
|
|
|
fprintf(script, "# Script ended at: %s\n", asctime(localtime(&tloc)));
|
|
|
|
fflush(script);
|
|
|
|
fclose(script);
|
|
|
|
} else {
|
|
|
|
script = fopen("sysinst.sh", "w");
|
2000-01-07 05:02:05 +03:00
|
|
|
if (script != NULL) {
|
|
|
|
sprintf(log_text[1], "Scripting: On");
|
|
|
|
scripting = 1;
|
|
|
|
fprintf(script, "#!/bin/sh\n");
|
|
|
|
fprintf(script, "# Script started at: %s\n",
|
|
|
|
asctime(localtime(&tloc)));
|
|
|
|
fflush(script);
|
|
|
|
} else {
|
|
|
|
msg_display(MSG_openfail, "script file", strerror(errno));
|
|
|
|
}
|
1999-01-21 11:02:17 +03:00
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
1997-09-27 03:02:53 +04:00
|
|
|
int
|
1998-06-20 17:05:48 +04:00
|
|
|
collect(int kind, char **buffer, const char *name, ...)
|
1997-09-27 03:02:53 +04:00
|
|
|
{
|
|
|
|
size_t nbytes; /* Number of bytes in buffer. */
|
|
|
|
size_t fbytes; /* Number of bytes in file. */
|
|
|
|
struct stat st; /* stat information. */
|
|
|
|
int ch;
|
|
|
|
FILE *f;
|
|
|
|
char fileorcmd [STRSIZE];
|
|
|
|
va_list ap;
|
|
|
|
|
1998-06-20 17:05:48 +04:00
|
|
|
va_start(ap, name);
|
|
|
|
vsnprintf(fileorcmd, STRSIZE, name, ap);
|
|
|
|
va_end(ap);
|
1997-09-27 03:02:53 +04:00
|
|
|
|
|
|
|
if (kind == T_FILE) {
|
|
|
|
/* Get the file information. */
|
1998-06-20 17:05:48 +04:00
|
|
|
if (stat(fileorcmd, &st)) {
|
1997-09-27 03:02:53 +04:00
|
|
|
*buffer = NULL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
fbytes = (size_t)st.st_size;
|
|
|
|
|
|
|
|
/* Open the file. */
|
1998-06-20 17:05:48 +04:00
|
|
|
f = fopen(fileorcmd, "r");
|
1997-09-27 03:02:53 +04:00
|
|
|
if (f == NULL) {
|
|
|
|
*buffer = NULL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Open the program. */
|
1998-06-20 17:05:48 +04:00
|
|
|
f = popen(fileorcmd, "r");
|
1997-09-27 03:02:53 +04:00
|
|
|
if (f == NULL) {
|
|
|
|
*buffer = NULL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
fbytes = BUFSIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fbytes == 0)
|
|
|
|
fbytes = BUFSIZE;
|
|
|
|
|
|
|
|
/* Allocate the buffer size. */
|
1998-06-20 17:05:48 +04:00
|
|
|
*buffer = (char *)malloc(fbytes + 1);
|
1997-09-27 03:02:53 +04:00
|
|
|
if (!*buffer)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* Read the buffer. */
|
|
|
|
nbytes = 0;
|
|
|
|
while (nbytes < fbytes && (ch = fgetc(f)) != EOF)
|
|
|
|
(*buffer)[nbytes++] = ch;
|
|
|
|
|
|
|
|
(*buffer)[nbytes] = 0;
|
|
|
|
|
|
|
|
if (kind == T_FILE)
|
|
|
|
fclose(f);
|
|
|
|
else
|
|
|
|
pclose(f);
|
|
|
|
|
|
|
|
return nbytes;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1997-11-02 06:45:27 +03:00
|
|
|
/*
|
|
|
|
* system(3), but with a debug wrapper.
|
1999-01-21 11:02:17 +03:00
|
|
|
* use only for curses sub-applications.
|
1997-11-02 06:45:27 +03:00
|
|
|
*/
|
1998-06-20 17:05:48 +04:00
|
|
|
int
|
|
|
|
do_system(execstr)
|
|
|
|
const char *execstr;
|
1997-11-02 06:45:27 +03:00
|
|
|
{
|
|
|
|
register int ret;
|
|
|
|
|
1998-06-20 17:05:48 +04:00
|
|
|
/*
|
|
|
|
* The following may be more than one function call. Can't just
|
|
|
|
* "return Xsystem (command);"
|
|
|
|
*/
|
1997-11-02 06:45:27 +03:00
|
|
|
|
1998-06-20 17:05:48 +04:00
|
|
|
ret = Xsystem(execstr);
|
|
|
|
return (ret);
|
1997-11-02 06:45:27 +03:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* build command tring for do_system() from anonymous args.
|
|
|
|
* XXX return result is in a static buffer.
|
|
|
|
*/
|
1998-06-20 17:05:48 +04:00
|
|
|
char *
|
1999-07-05 01:32:48 +04:00
|
|
|
va_prog_cmdstr(const char *cmd, va_list ap)
|
1997-11-02 06:45:27 +03:00
|
|
|
{
|
1998-06-20 17:05:48 +04:00
|
|
|
static char command[STRSIZE];
|
1997-11-02 06:45:27 +03:00
|
|
|
|
1998-08-10 06:23:45 +04:00
|
|
|
memset(command, 0, STRSIZE);
|
1998-06-20 17:05:48 +04:00
|
|
|
(void)vsnprintf(command, STRSIZE, cmd, ap);
|
|
|
|
return (command);
|
1997-11-02 06:45:27 +03:00
|
|
|
}
|
1997-09-27 03:02:53 +04:00
|
|
|
|
1997-11-02 06:45:27 +03:00
|
|
|
|
|
|
|
/*
|
1999-01-21 11:02:17 +03:00
|
|
|
* launch a program inside a subwindow, and report it's return status when done
|
1997-11-02 06:45:27 +03:00
|
|
|
*/
|
1999-01-21 11:02:17 +03:00
|
|
|
|
1998-06-20 17:05:48 +04:00
|
|
|
int
|
1999-01-21 11:02:17 +03:00
|
|
|
launch_subwin(actionwin, args, win, display)
|
|
|
|
WINDOW *actionwin;
|
|
|
|
char **args;
|
|
|
|
struct winsize win;
|
|
|
|
int display;
|
1997-11-02 06:45:27 +03:00
|
|
|
{
|
1999-01-21 11:02:17 +03:00
|
|
|
int xcor,ycor;
|
|
|
|
int n, i, j;
|
1999-03-22 12:02:47 +03:00
|
|
|
int selectfailed;
|
1999-01-21 11:02:17 +03:00
|
|
|
int status, master, slave;
|
|
|
|
fd_set active_fd_set, read_fd_set;
|
|
|
|
int dataflow[2];
|
|
|
|
pid_t child, subchild, pid;
|
|
|
|
char ibuf[MAXBUF], obuf[MAXBUF];
|
|
|
|
char *command, *p, *argzero, **origargs;
|
|
|
|
struct termios rtt;
|
|
|
|
struct termios tt;
|
|
|
|
|
|
|
|
pipe(dataflow);
|
|
|
|
|
|
|
|
argzero = *args;
|
|
|
|
origargs = args;
|
|
|
|
|
|
|
|
command = (char *)malloc(MAXBUF * sizeof(char));
|
|
|
|
for (p = *args; p != NULL; p = *++args) {
|
|
|
|
strcat(command, p);
|
|
|
|
strcat(command, " ");
|
1997-11-02 06:45:27 +03:00
|
|
|
}
|
1999-01-21 11:02:17 +03:00
|
|
|
(void)tcgetattr(STDIN_FILENO, &tt);
|
|
|
|
if (openpty(&master, &slave, NULL, &tt, &win) == -1)
|
|
|
|
return(1);
|
|
|
|
rtt = tt;
|
|
|
|
rtt.c_lflag &= ~ECHO;
|
|
|
|
(void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt);
|
|
|
|
|
1999-06-22 04:43:57 +04:00
|
|
|
/* ignore tty signals until we're done with subprocess setup */
|
2000-01-19 12:44:01 +03:00
|
|
|
endwin();
|
1999-06-22 04:43:57 +04:00
|
|
|
ttysig_ignore = 1;
|
|
|
|
|
1999-01-21 11:02:17 +03:00
|
|
|
switch(child=fork()) {
|
|
|
|
case -1:
|
1999-06-22 04:43:57 +04:00
|
|
|
ttysig_ignore = 0;
|
2000-01-19 12:44:01 +03:00
|
|
|
refresh();
|
1999-01-21 11:02:17 +03:00
|
|
|
return -1;
|
1999-03-22 12:02:47 +03:00
|
|
|
case 0:
|
1999-01-21 11:02:17 +03:00
|
|
|
(void)close(STDIN_FILENO);
|
|
|
|
subchild = fork();
|
|
|
|
if (subchild == 0) {
|
|
|
|
close(dataflow[0]);
|
|
|
|
for (;;) {
|
|
|
|
n = read(master, obuf, sizeof(obuf));
|
|
|
|
if (n <= 0)
|
|
|
|
break;
|
|
|
|
write(dataflow[1], obuf, n);
|
|
|
|
} /* while spinning */
|
|
|
|
_exit(EXIT_SUCCESS);
|
|
|
|
} /* subchild, child forks */
|
|
|
|
(void)close(master);
|
|
|
|
close(dataflow[1]);
|
|
|
|
close(dataflow[0]);
|
|
|
|
login_tty(slave);
|
|
|
|
if (logging) {
|
|
|
|
fprintf(log, "executing: %s\n", command);
|
|
|
|
fflush(log);
|
|
|
|
fclose(log);
|
|
|
|
}
|
|
|
|
if (scripting) {
|
|
|
|
fprintf(script, "%s\n", command);
|
|
|
|
fflush(script);
|
|
|
|
fclose(script);
|
|
|
|
}
|
|
|
|
execvp(argzero, origargs);
|
1999-03-11 19:48:27 +03:00
|
|
|
/* the parent will see this as the output from the
|
|
|
|
child */
|
1999-03-22 12:02:47 +03:00
|
|
|
warn("execvp %s", argzero);
|
1999-03-11 19:48:27 +03:00
|
|
|
_exit(EXIT_FAILURE);
|
1999-03-22 12:02:47 +03:00
|
|
|
break; /* end of child */
|
1999-06-22 04:43:57 +04:00
|
|
|
default:
|
|
|
|
/*
|
|
|
|
* we've set up the subprocess. forward tty signals to its * process group.
|
|
|
|
*/
|
|
|
|
ttysig_forward = child;
|
|
|
|
ttysig_ignore = 0;
|
2000-01-19 12:44:01 +03:00
|
|
|
refresh();
|
1999-06-22 04:43:57 +04:00
|
|
|
break;
|
1999-01-21 11:02:17 +03:00
|
|
|
}
|
|
|
|
close(dataflow[1]);
|
|
|
|
FD_ZERO(&active_fd_set);
|
|
|
|
FD_SET(dataflow[0], &active_fd_set);
|
|
|
|
FD_SET(STDIN_FILENO, &active_fd_set);
|
|
|
|
|
1999-03-22 12:02:47 +03:00
|
|
|
for (selectfailed = 0;;) {
|
|
|
|
if (selectfailed) {
|
|
|
|
char *msg = "select(2) failed but no child died?";
|
|
|
|
if(logging)
|
|
|
|
(void)fprintf(log, msg);
|
|
|
|
errx(1, msg);
|
|
|
|
}
|
1999-01-21 11:02:17 +03:00
|
|
|
read_fd_set = active_fd_set;
|
|
|
|
if (select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) {
|
1999-06-22 04:43:57 +04:00
|
|
|
if (errno == EINTR)
|
|
|
|
goto loop;
|
1999-01-21 11:02:17 +03:00
|
|
|
perror("select");
|
|
|
|
if (logging)
|
|
|
|
(void)fprintf(log, "select failure: %s\n", strerror(errno));
|
1999-03-22 12:02:47 +03:00
|
|
|
++selectfailed;
|
|
|
|
} else for (i = 0; i < FD_SETSIZE; ++i) {
|
1999-01-21 11:02:17 +03:00
|
|
|
if (FD_ISSET (i, &read_fd_set)) {
|
|
|
|
n = read(i, ibuf, MAXBUF);
|
|
|
|
if (i == STDIN_FILENO)
|
|
|
|
(void)write(master, ibuf, n);
|
|
|
|
for (j=0; j < n; j++) {
|
|
|
|
if (display) {
|
2000-01-19 12:44:01 +03:00
|
|
|
switch (ibuf[j]) {
|
|
|
|
case '\n':
|
1999-06-21 06:47:41 +04:00
|
|
|
getyx(actionwin, ycor, xcor);
|
2000-04-15 01:46:11 +04:00
|
|
|
if (ycor + 1 >= getmaxy(actionwin)) {
|
1999-06-21 06:31:17 +04:00
|
|
|
scroll(actionwin);
|
2000-04-15 01:46:11 +04:00
|
|
|
wmove(actionwin, getmaxy(actionwin) - 1, 0);
|
1999-06-21 06:31:17 +04:00
|
|
|
} else
|
1999-06-21 06:47:41 +04:00
|
|
|
wmove(actionwin, ycor + 1, 0);
|
2000-01-19 12:44:01 +03:00
|
|
|
break;
|
|
|
|
case '\r':
|
1999-06-21 06:47:41 +04:00
|
|
|
getyx(actionwin, ycor, xcor);
|
|
|
|
wmove(actionwin, ycor, 0);
|
2000-01-19 12:44:01 +03:00
|
|
|
break;
|
|
|
|
case '\b':
|
|
|
|
getyx(actionwin, ycor, xcor);
|
|
|
|
if (xcor > 0)
|
|
|
|
wmove(actionwin, ycor, xcor - 1);
|
|
|
|
break;
|
|
|
|
default:
|
1999-01-21 11:02:17 +03:00
|
|
|
waddch(actionwin, ibuf[j]);
|
2000-01-19 12:44:01 +03:00
|
|
|
break;
|
|
|
|
}
|
1999-06-21 06:47:41 +04:00
|
|
|
if (logging)
|
1999-01-21 11:02:17 +03:00
|
|
|
putc(ibuf[j], log);
|
|
|
|
}
|
|
|
|
}
|
2000-01-19 12:44:01 +03:00
|
|
|
if (display)
|
|
|
|
wrefresh(actionwin);
|
|
|
|
if (logging)
|
|
|
|
fflush(log);
|
1999-01-21 11:02:17 +03:00
|
|
|
}
|
1999-03-22 12:02:47 +03:00
|
|
|
}
|
1999-06-22 04:43:57 +04:00
|
|
|
loop:
|
1999-01-21 11:02:17 +03:00
|
|
|
pid = wait4(child, &status, WNOHANG, 0);
|
|
|
|
if (pid == child && (WIFEXITED(status) || WIFSIGNALED(status)))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
close(dataflow[0]); /* clean up our leaks */
|
|
|
|
close(master);
|
|
|
|
close(slave);
|
|
|
|
if (logging)
|
|
|
|
fflush(log);
|
|
|
|
|
1999-06-22 04:43:57 +04:00
|
|
|
/* from here on out, we take tty signals ourselves */
|
|
|
|
ttysig_forward = 0;
|
|
|
|
|
1999-01-21 11:02:17 +03:00
|
|
|
(void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &tt);
|
1999-06-22 04:43:57 +04:00
|
|
|
|
1999-01-21 11:02:17 +03:00
|
|
|
if (WIFEXITED(status))
|
|
|
|
return(WEXITSTATUS(status));
|
|
|
|
else if (WIFSIGNALED(status))
|
|
|
|
return(WTERMSIG(status));
|
|
|
|
else
|
|
|
|
return(0);
|
1997-09-27 03:02:53 +04:00
|
|
|
}
|
|
|
|
|
1997-11-02 06:45:27 +03:00
|
|
|
/*
|
1999-01-21 11:02:17 +03:00
|
|
|
* generic program runner. fatal and display can be set to
|
|
|
|
* 1 if you wish the output to be displayed, or an error to be
|
|
|
|
* fatal.
|
1997-11-02 06:45:27 +03:00
|
|
|
*/
|
1999-01-21 11:02:17 +03:00
|
|
|
|
|
|
|
int
|
1999-07-05 01:39:33 +04:00
|
|
|
run_prog(int fatal, int display, msg errmsg, const char *cmd, ...)
|
1997-11-02 06:45:27 +03:00
|
|
|
{
|
|
|
|
va_list ap;
|
1999-01-21 11:02:17 +03:00
|
|
|
struct winsize win;
|
1997-11-02 06:45:27 +03:00
|
|
|
int ret;
|
1999-01-21 11:02:17 +03:00
|
|
|
WINDOW *actionwin, *statuswin, *boxwin;
|
|
|
|
char buf2[MAXBUF];
|
|
|
|
char *command, *p, *args[51], **aps;
|
|
|
|
|
|
|
|
va_start(ap,cmd);
|
|
|
|
sprintf(buf2,"%s",va_prog_cmdstr(cmd,ap));
|
|
|
|
p = buf2;
|
|
|
|
command = strdup(buf2);
|
|
|
|
|
|
|
|
/* 51 strings and it's blown! */
|
|
|
|
for (aps = args; (*aps = strsep(&p, " ")) != NULL;)
|
|
|
|
if (**aps != '\0')
|
|
|
|
++aps;
|
|
|
|
|
|
|
|
(void)ioctl(STDIN_FILENO, TIOCGWINSZ, &win);
|
1999-03-09 22:30:00 +03:00
|
|
|
/* Apparently, we sometimes get 0x0 back, and that's not useful */
|
|
|
|
if (win.ws_row == 0)
|
|
|
|
win.ws_row = 24;
|
|
|
|
if (win.ws_col == 0)
|
|
|
|
win.ws_col = 80;
|
|
|
|
|
1999-01-21 11:02:17 +03:00
|
|
|
if (display) {
|
2000-01-19 12:44:01 +03:00
|
|
|
wclear(stdscr);
|
|
|
|
clearok(stdscr, 1);
|
|
|
|
refresh();
|
|
|
|
|
2000-01-13 21:52:21 +03:00
|
|
|
statuswin = subwin(stdscr, 3, win.ws_col, 0, 0);
|
1999-06-20 08:17:57 +04:00
|
|
|
if (statuswin == NULL) {
|
|
|
|
fprintf(stderr, "sysinst: failed to allocate"
|
|
|
|
" status window.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2000-01-19 12:44:01 +03:00
|
|
|
|
2000-01-19 11:46:26 +03:00
|
|
|
boxwin = subwin(stdscr, 1, win.ws_col, 3, 0);
|
1999-06-20 08:17:57 +04:00
|
|
|
if (boxwin == NULL) {
|
|
|
|
fprintf(stderr, "sysinst: failed to allocate"
|
|
|
|
" status box.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2000-01-19 12:44:01 +03:00
|
|
|
|
2000-01-13 21:52:21 +03:00
|
|
|
actionwin = subwin(stdscr, win.ws_row - 4, win.ws_col, 4, 0);
|
1999-06-20 08:17:57 +04:00
|
|
|
if (actionwin == NULL) {
|
|
|
|
fprintf(stderr, "sysinst: failed to allocate"
|
|
|
|
" output window.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
1999-01-21 11:02:17 +03:00
|
|
|
scrollok(actionwin, TRUE);
|
|
|
|
|
2000-01-13 21:52:21 +03:00
|
|
|
win.ws_row -= 4;
|
1999-01-21 11:02:17 +03:00
|
|
|
|
2000-01-19 12:44:01 +03:00
|
|
|
wmove(statuswin, 0, 5);
|
|
|
|
waddstr(statuswin, "Status: ");
|
|
|
|
wstandout(statuswin);
|
|
|
|
waddstr(statuswin, "Running");
|
|
|
|
wstandend(statuswin);
|
|
|
|
wmove(statuswin, 1, 4);
|
|
|
|
waddstr(statuswin, "Command: ");
|
|
|
|
wstandout(statuswin);
|
|
|
|
waddstr(statuswin, command);
|
|
|
|
wstandend(statuswin);
|
1999-01-21 11:02:17 +03:00
|
|
|
wrefresh(statuswin);
|
|
|
|
|
2000-01-13 21:52:21 +03:00
|
|
|
wmove(boxwin, 0, 0);
|
|
|
|
{
|
|
|
|
int n, m;
|
|
|
|
for (n = win.ws_col; (m = min(n, 30)) > 0; n -= m)
|
|
|
|
waddstr(boxwin,
|
|
|
|
"------------------------------" + 30 - m);
|
|
|
|
}
|
1999-01-21 11:02:17 +03:00
|
|
|
wrefresh(boxwin);
|
|
|
|
|
|
|
|
wrefresh(actionwin);
|
|
|
|
|
|
|
|
ret = launch_subwin(actionwin, args, win, 1);
|
|
|
|
|
|
|
|
wmove(statuswin, 0, 13);
|
|
|
|
wstandout(statuswin);
|
2000-01-19 12:44:01 +03:00
|
|
|
waddstr(statuswin, ret ? "Failed" : "Finished");
|
1999-01-21 11:02:17 +03:00
|
|
|
wstandend(statuswin);
|
2000-01-19 12:44:01 +03:00
|
|
|
waddstr(statuswin, " ");
|
1999-01-21 11:02:17 +03:00
|
|
|
wmove(statuswin, 2, 5);
|
- Add 2 functions in label.c, getpartoff()/getpartsize() used to let the user
enter partitions offet and size. The user can chose unit independantly of
the unit used for display ('M'/'c'/'s'). These functions do the proper
bound checks and alignement/roudups. Used in the edfspart menu and
i386 md_make_bsd_partitions() (other ports should do the change as
well).
- now that getpartsize() does the rigth thing, kill the swapadj hack (which was
buggy anyway).
- in i386 md_make_bsd_partitions(), don't propose defaults that don't fit on
the disk. If the disk is too small, fallback to custom instead.
- fix a bug in mbr.c, where the partition flags would not have always been
reset. sysinst created me a MBR with 2 active partition. The boot code
doesn't like it :)
- added a message for eventual mount failures.
- killed donewfs and extracting messages, as we run the commands in a
subwindow these messages just flashed on the screen.
- Changes a few exit(1) to return(1), to give the user a second chance.
- added msg_clear() or wclear(stdscr) in a place or two, to make
display a bit nicer.
- in run_cmd(), if the command succeeded, don't wait for the user to
press enter.
1999-04-12 02:40:19 +04:00
|
|
|
if (ret != 0)
|
|
|
|
waddstr(statuswin, "Press any key to continue");
|
1999-01-21 11:02:17 +03:00
|
|
|
wrefresh(statuswin);
|
- Add 2 functions in label.c, getpartoff()/getpartsize() used to let the user
enter partitions offet and size. The user can chose unit independantly of
the unit used for display ('M'/'c'/'s'). These functions do the proper
bound checks and alignement/roudups. Used in the edfspart menu and
i386 md_make_bsd_partitions() (other ports should do the change as
well).
- now that getpartsize() does the rigth thing, kill the swapadj hack (which was
buggy anyway).
- in i386 md_make_bsd_partitions(), don't propose defaults that don't fit on
the disk. If the disk is too small, fallback to custom instead.
- fix a bug in mbr.c, where the partition flags would not have always been
reset. sysinst created me a MBR with 2 active partition. The boot code
doesn't like it :)
- added a message for eventual mount failures.
- killed donewfs and extracting messages, as we run the commands in a
subwindow these messages just flashed on the screen.
- Changes a few exit(1) to return(1), to give the user a second chance.
- added msg_clear() or wclear(stdscr) in a place or two, to make
display a bit nicer.
- in run_cmd(), if the command succeeded, don't wait for the user to
press enter.
1999-04-12 02:40:19 +04:00
|
|
|
if (ret != 0)
|
|
|
|
(void)getchar();
|
1999-01-21 11:02:17 +03:00
|
|
|
|
|
|
|
/* clean things up */
|
|
|
|
delwin(actionwin);
|
|
|
|
delwin(boxwin);
|
|
|
|
delwin(statuswin);
|
2000-01-19 12:44:01 +03:00
|
|
|
|
|
|
|
wclear(stdscr);
|
|
|
|
clearok(stdscr, 1);
|
1999-01-21 11:02:17 +03:00
|
|
|
refresh();
|
|
|
|
} else { /* display */
|
|
|
|
ret = launch_subwin(NULL, args, win, 0);
|
1997-11-02 06:45:27 +03:00
|
|
|
}
|
1999-01-21 11:02:17 +03:00
|
|
|
va_end(ap);
|
1999-04-09 14:24:38 +04:00
|
|
|
if (fatal && ret != 0)
|
1999-01-21 11:02:17 +03:00
|
|
|
exit(ret);
|
1999-07-05 01:39:33 +04:00
|
|
|
if (ret && errmsg != MSG_NONE) {
|
|
|
|
msg_display(errmsg, command);
|
1999-04-09 14:24:38 +04:00
|
|
|
process_menu(MENU_ok);
|
|
|
|
}
|
|
|
|
return(ret);
|
1997-11-02 06:45:27 +03:00
|
|
|
}
|