[BACK]Return to run.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / distrib / utils / sysinst

Annotation of src/distrib/utils/sysinst/run.c, Revision 1.33

1.33    ! mrg         1: /*     $NetBSD: run.c,v 1.32 2000/10/11 23:47:56 fvdl Exp $    */
1.1       phil        2:
                      3: /*
                      4:  * Copyright 1997 Piermont Information Systems Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * Written by Philip A. Nelson for Piermont Information Systems Inc.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
1.16      cgd        19:  *      This product includes software developed for the NetBSD Project by
1.1       phil       20:  *      Piermont Information Systems Inc.
                     21:  * 4. The name of Piermont Information Systems Inc. may not be used to endorse
                     22:  *    or promote products derived from this software without specific prior
                     23:  *    written permission.
                     24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
                     26:  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     28:  * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
                     29:  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     30:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     31:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     32:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     33:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     34:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
                     35:  * THE POSSIBILITY OF SUCH DAMAGE.
                     36:  *
                     37:  */
                     38:
                     39: /* run.c -- routines to interact with other programs. */
                     40:
1.7       garbled    41: /* XXX write return codes ignored. XXX */
                     42:
                     43: #include <errno.h>
1.1       phil       44: #include <stdio.h>
                     45: #include <stdarg.h>
                     46: #include <stdlib.h>
1.7       garbled    47: #include <unistd.h>
                     48: #include <fcntl.h>
                     49: #include <curses.h>
                     50: #include <termios.h>
                     51: #include <util.h>
                     52: #include <err.h>
                     53: #include <sys/ioctl.h>
1.1       phil       54: #include <sys/types.h>
1.7       garbled    55: #include <sys/wait.h>
1.1       phil       56: #include <sys/stat.h>
                     57: #include "defs.h"
                     58:
1.7       garbled    59: #include "menu_defs.h"
1.3       jonathan   60: #include "msg_defs.h"
                     61:
1.7       garbled    62: #define MAXBUF 256
                     63:
1.1       phil       64: #ifdef DEBUG
1.2       phil       65: #define Xsystem(y) printf ("%s\n", y), 0
1.1       phil       66: #else
                     67: #define Xsystem(y) system(y)
                     68: #endif
1.7       garbled    69:
1.3       jonathan   70: /*
                     71:  * local prototypes
                     72:  */
1.33    ! mrg        73: char* va_prog_cmdstr (const char *cmd, va_list ap);
        !            74: int launch_subwin (WINDOW *actionwin, char **args, struct winsize *win, int display);
        !            75: int log_flip (menudesc *);
        !            76: int script_flip (menudesc *);
1.7       garbled    77:
                     78: #define BUFSIZE 4096
                     79:
                     80: char log_text[2][30] = {"Logging: Off", "Scripting: Off"};
                     81:
                     82: menu_ent logmenu [2] = {
                     83:        { log_text[0], OPT_NOMENU, 0, log_flip},
                     84:        { log_text[1], OPT_NOMENU, 0, script_flip} };
                     85:
                     86:
                     87: void
                     88: do_logging(void)
                     89: {
                     90:        int menu_no;
                     91:
1.17      cgd        92:        menu_no = new_menu ("Logging Functions", logmenu, 2, -1, 12,
                     93:                0, 20, MC_SCROLL, NULL, NULL, "Pick an option to turn on or off.\n");
1.7       garbled    94:
                     95:        if (menu_no < 0) {
                     96:                (void)fprintf(stderr, "Dynamic menu creation failed.\n");
                     97:                if (logging)
                     98:                        (void)fprintf(log, "Dynamic menu creation failed.\n");
                     99:                exit(EXIT_FAILURE);
                    100:        }
                    101:        process_menu(menu_no);
                    102:        free_menu(menu_no);
                    103: }
                    104:
                    105: int
1.31      hubertf   106: log_flip(menudesc *m)
1.7       garbled   107: {
                    108:        time_t tloc;
                    109:
                    110:        (void)time(&tloc);
                    111:        if (logging == 1) {
                    112:                sprintf(log_text[0], "Logging: Off");
                    113:                logging = 0;
                    114:                fprintf(log, "Log ended at: %s\n", asctime(localtime(&tloc)));
                    115:                fflush(log);
                    116:                fclose(log);
                    117:        } else {
                    118:                log = fopen("sysinst.log", "a");
1.25      jeremy    119:                if (log != NULL) {
                    120:                        sprintf(log_text[0], "Logging: On");
                    121:                        logging = 1;
                    122:                        fprintf(log, "Log started at: %s\n", asctime(localtime(&tloc)));
                    123:                        fflush(log);
                    124:                } else {
                    125:                        msg_display(MSG_openfail, "log file", strerror(errno));
                    126:                }
1.7       garbled   127:        }
                    128:        return(0);
                    129: }
1.3       jonathan  130:
1.7       garbled   131: int
1.31      hubertf   132: script_flip(menudesc *m)
1.7       garbled   133: {
                    134:        time_t tloc;
1.3       jonathan  135:
1.7       garbled   136:        (void)time(&tloc);
                    137:        if (scripting == 1) {
                    138:                sprintf(log_text[1], "Scripting: Off");
                    139:                scripting = 0;
                    140:                fprintf(script, "# Script ended at: %s\n", asctime(localtime(&tloc)));
                    141:                fflush(script);
                    142:                fclose(script);
                    143:        } else {
                    144:                script = fopen("sysinst.sh", "w");
1.25      jeremy    145:                if (script != NULL) {
                    146:                        sprintf(log_text[1], "Scripting: On");
                    147:                        scripting = 1;
                    148:                        fprintf(script, "#!/bin/sh\n");
                    149:                        fprintf(script, "# Script started at: %s\n",
                    150:                            asctime(localtime(&tloc)));
                    151:                        fflush(script);
                    152:                } else {
                    153:                        msg_display(MSG_openfail, "script file", strerror(errno));
                    154:                }
1.7       garbled   155:        }
                    156:        return(0);
                    157: }
1.1       phil      158:
                    159: int
1.5       mrg       160: collect(int kind, char **buffer, const char *name, ...)
1.1       phil      161: {
                    162:        size_t nbytes;          /* Number of bytes in buffer. */
                    163:        size_t fbytes;          /* Number of bytes in file. */
                    164:        struct stat st;         /* stat information. */
                    165:        int ch;
                    166:        FILE *f;
                    167:        char fileorcmd [STRSIZE];
                    168:        va_list ap;
                    169:
1.5       mrg       170:        va_start(ap, name);
                    171:        vsnprintf(fileorcmd, STRSIZE, name, ap);
                    172:        va_end(ap);
1.1       phil      173:
                    174:        if (kind == T_FILE) {
                    175:                /* Get the file information. */
1.5       mrg       176:                if (stat(fileorcmd, &st)) {
1.1       phil      177:                        *buffer = NULL;
                    178:                        return -1;
                    179:                }
                    180:                fbytes = (size_t)st.st_size;
                    181:
                    182:                /* Open the file. */
1.5       mrg       183:                f = fopen(fileorcmd, "r");
1.1       phil      184:                if (f == NULL) {
                    185:                        *buffer = NULL;
                    186:                        return -1;
                    187:                }
                    188:        } else {
                    189:                /* Open the program. */
1.5       mrg       190:                f = popen(fileorcmd, "r");
1.1       phil      191:                if (f == NULL) {
                    192:                        *buffer = NULL;
                    193:                        return -1;
                    194:                }
                    195:                fbytes = BUFSIZE;
                    196:        }
                    197:
                    198:        if (fbytes == 0)
                    199:                fbytes = BUFSIZE;
                    200:
                    201:        /* Allocate the buffer size. */
1.5       mrg       202:        *buffer = (char *)malloc(fbytes + 1);
1.1       phil      203:        if (!*buffer)
                    204:                return -1;
                    205:
                    206:        /* Read the buffer. */
                    207:        nbytes = 0;
                    208:        while (nbytes < fbytes && (ch = fgetc(f)) != EOF)
                    209:                (*buffer)[nbytes++] = ch;
                    210:
                    211:        (*buffer)[nbytes] = 0;
                    212:
                    213:        if (kind == T_FILE)
                    214:                fclose(f);
                    215:        else
                    216:                pclose(f);
                    217:
                    218:        return nbytes;
                    219: }
                    220:
                    221:
1.3       jonathan  222: /*
                    223:  * system(3), but with a debug wrapper.
1.7       garbled   224:  * use only for curses sub-applications.
1.3       jonathan  225:  */
1.5       mrg       226: int
                    227: do_system(execstr)
                    228:        const char *execstr;
1.3       jonathan  229: {
                    230:        register int ret;
                    231:
1.5       mrg       232:        /*
                    233:         * The following may be more than one function call.  Can't just
                    234:         * "return Xsystem (command);"
                    235:         */
1.3       jonathan  236:
1.5       mrg       237:        ret = Xsystem(execstr);
                    238:        return (ret);
1.3       jonathan  239:
                    240: }
                    241:
                    242: /*
                    243:  *  build command tring for do_system() from anonymous args.
                    244:  *  XXX return result is in a static buffer.
                    245:  */
1.5       mrg       246: char *
1.22      cgd       247: va_prog_cmdstr(const char *cmd, va_list ap)
1.3       jonathan  248: {
1.5       mrg       249:        static char command[STRSIZE];
1.3       jonathan  250:
1.6       perry     251:        memset(command, 0, STRSIZE);
1.5       mrg       252:        (void)vsnprintf(command, STRSIZE, cmd, ap);
                    253:        return (command);
1.3       jonathan  254: }
1.7       garbled   255:
1.3       jonathan  256:
1.5       mrg       257: /*
1.7       garbled   258:  * launch a program inside a subwindow, and report it's return status when done
1.5       mrg       259:  */
1.7       garbled   260:
1.5       mrg       261: int
1.32      fvdl      262: launch_subwin(actionwin, args, win, flags)
1.7       garbled   263:        WINDOW *actionwin;
                    264:        char **args;
1.32      fvdl      265:        struct winsize *win;
                    266:        int flags;
1.1       phil      267: {
1.7       garbled   268:        int xcor,ycor;
                    269:        int n, i, j;
1.11      ross      270:        int selectfailed;
1.7       garbled   271:        int status, master, slave;
                    272:        fd_set active_fd_set, read_fd_set;
                    273:        int dataflow[2];
                    274:        pid_t child, subchild, pid;
                    275:        char ibuf[MAXBUF], obuf[MAXBUF];
                    276:        char *command, *p, *argzero, **origargs;
1.32      fvdl      277:        char pktdata;
1.7       garbled   278:        struct termios rtt;
                    279:        struct termios tt;
                    280:
                    281:        pipe(dataflow);
                    282:
                    283:        argzero = *args;
                    284:        origargs = args;
                    285:
                    286:        command = (char *)malloc(MAXBUF * sizeof(char));
                    287:        for (p = *args; p != NULL; p = *++args) {
                    288:                strcat(command, p);
                    289:                strcat(command, " ");
                    290:        }
                    291:        (void)tcgetattr(STDIN_FILENO, &tt);
1.32      fvdl      292:        if (openpty(&master, &slave, NULL, &tt, win) == -1)
1.7       garbled   293:                return(1);
1.32      fvdl      294: #if 0
1.7       garbled   295:        rtt = tt;
1.32      fvdl      296:        rtt.c_lflag |= (ICANON|ECHO);
1.7       garbled   297:        (void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt);
1.32      fvdl      298: #endif
                    299:        rtt = tt;
1.1       phil      300:
1.21      cgd       301:        /* ignore tty signals until we're done with subprocess setup */
1.28      mycroft   302:        endwin();
1.21      cgd       303:        ttysig_ignore = 1;
1.32      fvdl      304:        ioctl(master, TIOCPKT, &ttysig_ignore);
1.21      cgd       305:
1.7       garbled   306:        switch(child=fork()) {
                    307:        case -1:
1.21      cgd       308:                ttysig_ignore = 0;
1.28      mycroft   309:                refresh();
1.7       garbled   310:                return -1;
1.11      ross      311:        case 0:
1.7       garbled   312:                (void)close(STDIN_FILENO);
                    313:                subchild = fork();
                    314:                if (subchild == 0) {
                    315:                        close(dataflow[0]);
                    316:                        for (;;) {
                    317:                                n = read(master, obuf, sizeof(obuf));
                    318:                                if (n <= 0)
                    319:                                        break;
                    320:                                write(dataflow[1], obuf, n);
                    321:                        } /* while spinning */
                    322:                        _exit(EXIT_SUCCESS);
                    323:                } /* subchild, child forks */
                    324:                (void)close(master);
                    325:                close(dataflow[1]);
                    326:                close(dataflow[0]);
1.32      fvdl      327:                rtt = tt;
                    328:                rtt.c_lflag |= (ICANON|ECHO);
                    329:                (void)tcsetattr(slave, TCSANOW, &rtt);
1.7       garbled   330:                login_tty(slave);
                    331:                if (logging) {
                    332:                        fprintf(log, "executing: %s\n", command);
                    333:                        fflush(log);
                    334:                        fclose(log);
                    335:                }
                    336:                if (scripting) {
                    337:                        fprintf(script, "%s\n", command);
                    338:                        fflush(script);
                    339:                        fclose(script);
                    340:                }
1.32      fvdl      341:                /*
                    342:                 * If target_prefix == "", the chroot will fail, but
                    343:                 * that's ok, since we don't need it then.
                    344:                 */
                    345:                if ((flags & RUN_CHROOT) != 0)
                    346:                        chroot(target_prefix());
1.7       garbled   347:                execvp(argzero, origargs);
1.10      marc      348:                /* the parent will see this as the output from the
                    349:                   child */
1.11      ross      350:                warn("execvp %s", argzero);
1.10      marc      351:                _exit(EXIT_FAILURE);
1.11      ross      352:                break; /* end of child */
1.21      cgd       353:        default:
                    354:                /*
                    355:                 * we've set up the subprocess.  forward tty signals to its                      * process group.
                    356:                 */
                    357:                ttysig_forward = child;
                    358:                ttysig_ignore = 0;
1.28      mycroft   359:                refresh();
1.21      cgd       360:                break;
1.7       garbled   361:        }
                    362:        close(dataflow[1]);
                    363:        FD_ZERO(&active_fd_set);
                    364:        FD_SET(dataflow[0], &active_fd_set);
                    365:        FD_SET(STDIN_FILENO, &active_fd_set);
                    366:
1.11      ross      367:        for (selectfailed = 0;;) {
                    368:                if (selectfailed) {
                    369:                        char *msg = "select(2) failed but no child died?";
                    370:                        if(logging)
                    371:                                (void)fprintf(log, msg);
                    372:                        errx(1, msg);
                    373:                }
1.7       garbled   374:                read_fd_set = active_fd_set;
                    375:                if (select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) {
1.21      cgd       376:                        if (errno == EINTR)
                    377:                                goto loop;
1.7       garbled   378:                        perror("select");
                    379:                        if (logging)
                    380:                                (void)fprintf(log, "select failure: %s\n", strerror(errno));
1.11      ross      381:                        ++selectfailed;
                    382:                } else for (i = 0; i < FD_SETSIZE; ++i) {
1.7       garbled   383:                        if (FD_ISSET (i, &read_fd_set)) {
                    384:                                n = read(i, ibuf, MAXBUF);
1.32      fvdl      385:                                if (i == STDIN_FILENO) {
1.7       garbled   386:                                        (void)write(master, ibuf, n);
1.32      fvdl      387:                                        if ((rtt.c_lflag & ECHO) == 0)
                    388:                                                goto enddisp;
                    389:                                }
                    390:                                pktdata = ibuf[0];
                    391:                                if (pktdata != 0 && i != STDIN_FILENO) {
                    392:                                        if (pktdata & TIOCPKT_IOCTL)
                    393:                                                rtt = *(struct termios *)ibuf;
                    394:                                        goto enddisp;
                    395:                                }
                    396:                                for (j=1; j < n; j++) {
                    397:                                        if ((flags & RUN_DISPLAY) != 0) {
1.28      mycroft   398:                                                switch (ibuf[j]) {
                    399:                                                case '\n':
1.19      cgd       400:                                                        getyx(actionwin, ycor, xcor);
1.30      thorpej   401:                                                        if (ycor + 1 >= getmaxy(actionwin)) {
1.18      cgd       402:                                                                scroll(actionwin);
1.30      thorpej   403:                                                                wmove(actionwin, getmaxy(actionwin) - 1, 0);
1.18      cgd       404:                                                        } else
1.19      cgd       405:                                                                wmove(actionwin, ycor + 1, 0);
1.28      mycroft   406:                                                        break;
                    407:                                                case '\r':
1.19      cgd       408:                                                        getyx(actionwin, ycor, xcor);
                    409:                                                        wmove(actionwin, ycor, 0);
1.28      mycroft   410:                                                        break;
                    411:                                                case '\b':
                    412:                                                        getyx(actionwin, ycor, xcor);
                    413:                                                        if (xcor > 0)
                    414:                                                                wmove(actionwin, ycor, xcor - 1);
                    415:                                                        break;
                    416:                                                default:
1.7       garbled   417:                                                        waddch(actionwin, ibuf[j]);
1.28      mycroft   418:                                                        break;
                    419:                                                }
1.19      cgd       420:                                                if (logging)
1.7       garbled   421:                                                        putc(ibuf[j], log);
                    422:                                        }
                    423:                                }
1.32      fvdl      424: enddisp:
                    425:                                if ((flags & RUN_DISPLAY) != 0)
1.28      mycroft   426:                                        wrefresh(actionwin);
                    427:                                if (logging)
                    428:                                        fflush(log);
1.7       garbled   429:                        }
1.11      ross      430:                }
1.21      cgd       431: loop:
1.7       garbled   432:                pid = wait4(child, &status, WNOHANG, 0);
                    433:                if (pid == child && (WIFEXITED(status) || WIFSIGNALED(status)))
                    434:                        break;
                    435:        }
                    436:        close(dataflow[0]); /* clean up our leaks */
                    437:        close(master);
                    438:        close(slave);
                    439:        if (logging)
                    440:                fflush(log);
                    441:
1.21      cgd       442:        /* from here on out, we take tty signals ourselves */
                    443:        ttysig_forward = 0;
                    444:
1.7       garbled   445:        (void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &tt);
1.21      cgd       446:
1.7       garbled   447:        if (WIFEXITED(status))
                    448:                return(WEXITSTATUS(status));
                    449:        else if (WIFSIGNALED(status))
                    450:                return(WTERMSIG(status));
                    451:        else
                    452:                return(0);
1.3       jonathan  453: }
                    454:
                    455: /*
1.7       garbled   456:  * generic program runner.  fatal and display can be set to
                    457:  * 1 if you wish the output to be displayed, or an error to be
                    458:  * fatal.
1.3       jonathan  459:  */
1.7       garbled   460:
1.5       mrg       461: int
1.32      fvdl      462: run_prog(int flags, msg errmsg, const char *cmd, ...)
1.3       jonathan  463: {
                    464:        va_list ap;
1.7       garbled   465:        struct winsize win;
1.3       jonathan  466:        int ret;
1.7       garbled   467:        WINDOW *actionwin, *statuswin, *boxwin;
                    468:        char buf2[MAXBUF];
                    469:        char *command, *p, *args[51], **aps;
                    470:
                    471:        va_start(ap,cmd);
                    472:        sprintf(buf2,"%s",va_prog_cmdstr(cmd,ap));
                    473:        p = buf2;
                    474:        command = strdup(buf2);
                    475:
                    476:        /* 51 strings and it's blown! */
                    477:        for (aps = args; (*aps = strsep(&p, " ")) != NULL;)
                    478:                if (**aps != '\0')
                    479:                        ++aps;
                    480:
                    481:        (void)ioctl(STDIN_FILENO, TIOCGWINSZ, &win);
1.9       he        482:        /* Apparently, we sometimes get 0x0 back, and that's not useful */
                    483:        if (win.ws_row == 0)
                    484:                win.ws_row = 24;
                    485:        if (win.ws_col == 0)
                    486:                win.ws_col = 80;
                    487:
1.32      fvdl      488:        if ((flags & RUN_SYSTEM) != 0) {
                    489:                if ((flags & RUN_CHROOT) != 0)
                    490:                        chroot(target_prefix());
                    491:                ret = system(command);
                    492:        } else if ((flags & RUN_DISPLAY) != 0) {
1.28      mycroft   493:                wclear(stdscr);
                    494:                clearok(stdscr, 1);
1.32      fvdl      495:                touchwin(stdscr);
1.28      mycroft   496:                refresh();
                    497:
1.32      fvdl      498:                if ((flags & RUN_FULLSCREEN) != 0) {
                    499:                        ret = launch_subwin(stdscr, args, &win, flags);
                    500:                        if (ret != 0) {
                    501:                                waddstr(stdscr, "Press any key to continue");
                    502:                                wrefresh(stdscr);
                    503:                                getchar();
                    504:                        }
                    505:                        goto done;
                    506:                }
                    507:
1.26      mycroft   508:                statuswin = subwin(stdscr, 3, win.ws_col, 0, 0);
1.15      garbled   509:                if (statuswin == NULL) {
                    510:                        fprintf(stderr, "sysinst: failed to allocate"
                    511:                            " status window.\n");
                    512:                        exit(1);
                    513:                }
1.28      mycroft   514:
1.27      mycroft   515:                boxwin = subwin(stdscr, 1, win.ws_col, 3, 0);
1.15      garbled   516:                if (boxwin == NULL) {
                    517:                        fprintf(stderr, "sysinst: failed to allocate"
                    518:                            " status box.\n");
                    519:                        exit(1);
                    520:                }
1.28      mycroft   521:
1.26      mycroft   522:                actionwin = subwin(stdscr, win.ws_row - 4, win.ws_col, 4, 0);
1.15      garbled   523:                if (actionwin == NULL) {
                    524:                        fprintf(stderr, "sysinst: failed to allocate"
1.32      fvdl      525:                                    " output window.\n");
1.15      garbled   526:                        exit(1);
                    527:                }
1.7       garbled   528:                scrollok(actionwin, TRUE);
                    529:
1.26      mycroft   530:                win.ws_row -= 4;
1.7       garbled   531:
1.28      mycroft   532:                wmove(statuswin, 0, 5);
                    533:                waddstr(statuswin, "Status: ");
                    534:                wstandout(statuswin);
                    535:                waddstr(statuswin, "Running");
                    536:                wstandend(statuswin);
                    537:                wmove(statuswin, 1, 4);
                    538:                waddstr(statuswin, "Command: ");
                    539:                wstandout(statuswin);
                    540:                waddstr(statuswin, command);
                    541:                wstandend(statuswin);
1.7       garbled   542:                wrefresh(statuswin);
                    543:
1.26      mycroft   544:                wmove(boxwin, 0, 0);
                    545:                {
                    546:                        int n, m;
                    547:                        for (n = win.ws_col; (m = min(n, 30)) > 0; n -= m)
                    548:                                waddstr(boxwin,
                    549:                                    "------------------------------" + 30 - m);
                    550:                }
1.7       garbled   551:                wrefresh(boxwin);
                    552:
                    553:                wrefresh(actionwin);
                    554:
1.32      fvdl      555:                ret = launch_subwin(actionwin, args, &win, flags);
1.7       garbled   556:
                    557:                wmove(statuswin, 0, 13);
                    558:                wstandout(statuswin);
1.28      mycroft   559:                waddstr(statuswin, ret ? "Failed" : "Finished");
1.7       garbled   560:                wstandend(statuswin);
1.28      mycroft   561:                waddstr(statuswin, "  ");
1.7       garbled   562:                wmove(statuswin, 2, 5);
1.13      bouyer    563:                if (ret != 0)
                    564:                        waddstr(statuswin, "Press any key to continue");
1.7       garbled   565:                wrefresh(statuswin);
1.13      bouyer    566:                if (ret != 0)
                    567:                        (void)getchar();
1.7       garbled   568:
                    569:                /* clean things up */
                    570:                delwin(actionwin);
                    571:                delwin(boxwin);
                    572:                delwin(statuswin);
1.32      fvdl      573: done:
1.28      mycroft   574:                wclear(stdscr);
1.32      fvdl      575:                touchwin(stdscr);
1.28      mycroft   576:                clearok(stdscr, 1);
1.7       garbled   577:                refresh();
                    578:        } else { /* display */
1.32      fvdl      579:                ret = launch_subwin(NULL, args, &win, flags);
1.7       garbled   580:        }
1.5       mrg       581:        va_end(ap);
1.32      fvdl      582:        if ((flags & RUN_FATAL) != 0 && ret != 0)
1.5       mrg       583:                exit(ret);
1.23      cgd       584:        if (ret && errmsg != MSG_NONE) {
                    585:                msg_display(errmsg, command);
1.12      bouyer    586:                process_menu(MENU_ok);
                    587:        }
                    588:        return(ret);
1.3       jonathan  589: }

CVSweb <webmaster@jp.NetBSD.org>