home *** CD-ROM | disk | FTP | other *** search
- /* Win.c */
-
- #include "Sys.h"
- #include "Curses.h"
-
- #include <errno.h>
- #include <signal.h>
- #include <stdlib.h>
-
- #include "Util.h"
- #include "Main.h"
- #include "Version.h"
- #include "Bookmark.h"
- #include "RCmd.h"
- #include "LGets.h"
- #include "GetPass.h"
-
-
- #ifdef USE_CURSES
-
- #include "WGets.h"
-
- extern int endwin(void);
- extern long gEventNumber;
- WINDOW *gListWin;
- WINDOW *gInputWin;
- WINDOW *gPromptWin;
- WINDOW *gBarWin;
- int gCurRow, gLastRow, gSkipToEnd;
- int gPageNum;
- int gMultiLineMode = 0;
- int gPendingNL = 0;
- int gBackgroundProcessing = 0;
- int gUsingDefaultBar = 0;
- int gUsingTmpCenterBar = 0;
- string gBarLeft, gBarCenter, gBarRight;
-
- /* Other protos, whose parameters aren't WINDOW *ptrs, are in Win.h */
- void WAddCenteredStr(WINDOW *, int, char *);
- void WAttr(WINDOW *w, int attr, int on);
-
- extern WINDOW *gPrefsWin, *gHostWin;
-
- #endif /* USE_CURSES */
-
- string gPrompt = kLineModePrompt;
- int gWinInit = 0;
- char *gSprintfBuf = NULL;
- int gScreenWidth = 80;
-
- extern longstring gRemoteCWD;
- extern longstring gLockFileName;
- extern int gConnected, gVerbosity;
- extern Bookmark gRmtInfo;
- extern string gHost;
- extern int gStdout, gRealStdout, gOtherSessionRunning;
- extern FILE *gTraceLogFile;
- extern int gDebug, gTrace;
- extern LineList gCmdHistory;
- extern int gVisualMode, gIsToTTY, gIsFromTTY, gStartup;
- extern int gRedialModeEnabled;
-
-
- void EndWin(void)
- {
- if (gWinInit) {
- gWinInit = 0;
- #ifdef USE_CURSES
- if (gEventNumber > 0L) {
- clear();
- refresh();
- }
- endwin();
- #endif /* USE_CURSES */
- }
- } /* EndWin */
-
-
-
-
- void Exit(int exitStatus)
- {
- if (gOtherSessionRunning == 0) {
- (void) UNLINK(gLockFileName);
- }
- EndWin();
- exit(exitStatus);
- } /* Exit */
-
-
-
- static void
- SigTerm(void)
- {
- Exit(kExitSignal);
- } /* SigTerm */
-
-
-
-
- void SaveScreen(void)
- {
- #ifdef USE_CURSES
- if (gWinInit) {
- /* Clearing the screen is necessary
- * because ncurses doesn't move the
- * cursor to the bottom left.
- *
- * This also causes the restore
- * operation to require that we paint
- * all our windows by hand, because we
- * have just left the screen blank so
- * when refresh gets called in the
- * restore it just returns the screen
- * to blank.
- *
- * If it weren't for this screen clear,
- * we would be able to get away with
- * just doing an endwin(), the shell,
- * and then a refresh() without us
- * re-drawing any windows manually.
- */
- clear();
- refresh();
- endwin();
- fflush(stdout);
- fflush(stderr);
- }
- #endif /* USE_CURSES */
- } /* SaveScreen */
-
-
-
- static void TTYWaitForReturn(void)
- {
- int tty;
- int junk;
-
- tty = open("/dev/tty", O_RDWR);
- if (tty != -1) {
- write(tty, "[Hit return]", 12);
- read(tty, &junk, 1);
- close(tty);
- }
- } /* TTYWaitForReturn */
-
-
-
- void RestoreScreen(int pressKey)
- {
- #ifdef USE_CURSES
- if (gWinInit) {
- if (pressKey) {
- # if (CURSES_SHELL_BUG == 0)
- TTYWaitForReturn();
- # else
- sleep(2);
- # endif
- }
- refresh();
- UpdateScreen(1);
- }
- #endif /* USE_CURSES */
- } /* RestoreScreen */
-
-
-
- void Beep(int on)
- {
- static time_t lastBeepTime = 0;
- time_t now;
-
- time(&now);
-
- /* Don't flood the user with beeps. Once per two seconds is reasonable. */
- if ((on > 0) && ((int) (now - lastBeepTime) > 1)) {
- #ifdef USE_CURSES
- if (gWinInit)
- beep();
- else
- #endif
- {
- fprintf(stderr, "\007"); /* ^G */
- fflush(stderr);
- }
- }
- lastBeepTime = now;
- } /* Beep */
-
-
-
-
- #ifdef USE_CURSES
- /* Many old curses libraries don't support wattron() and its attributes.
- * They should support wstandout() though. This routine is an attempt
- * to use the best substitute available, depending on what the curses
- * library has.
- */
- void WAttr(WINDOW *w, int attr, int on)
- {
- /* Define PLAIN_TEXT_ONLY if you have the attributes, but don't want
- * to use them.
- */
- #ifndef PLAIN_TEXT_ONLY
- #ifdef A_REVERSE
- if (attr & kReverse) {
- if (on)
- wattron(w, A_REVERSE);
- else
- wattroff(w, A_REVERSE);
- }
- #else
- if (attr & kReverse) {
- if (on)
- wstandout(w);
- else
- wstandend(w);
-
- /* Nothing else will be done anyway, so just return now. */
- return;
- }
- #endif /* A_REVERSE */
-
- #ifdef A_BOLD
- if (attr & kBold) {
- if (on)
- wattron(w, A_BOLD);
- else
- wattroff(w, A_BOLD);
- }
- #else
- /* Do nothing. Plain is best substitute. */
- #endif /* A_BOLD */
-
- #ifdef A_UNDERLINE
- if (attr & kUnderline) {
- if (on)
- wattron(w, A_UNDERLINE);
- else
- wattroff(w, A_UNDERLINE);
- }
- #else
- /* Try using standout mode in place of underline. */
- if (attr & kUnderline) {
- if (on)
- wstandout(w);
- else
- wstandend(w);
-
- /* Nothing else will be done anyway, so just return now. */
- return;
- }
- #endif /* A_UNDERLINE */
-
- #ifdef A_DIM
- if (attr & kDim) {
- if (on)
- wattron(w, A_DIM);
- else
- wattroff(w, A_DIM);
- }
- #else
- /* Do nothing. Plain is best substitute. */
- #endif /* A_DIM */
-
- #ifdef A_NORMAL
- if (attr == kNormal) {
- wattrset(w, A_NORMAL);
- return;
- }
- #else
- /* At least make sure standout mode is off. */
- if (attr == kNormal) {
- wstandend(w);
- return;
- }
- #endif /* A_NORMAL */
- #endif /* PLAIN_TEXT_ONLY */
- } /* WAttr */
- #endif /* USE_CURSES */
-
-
-
-
- void UpdateScreen(int wholeScreen)
- {
- #ifdef USE_CURSES
- if (gWinInit) {
- if (wholeScreen) {
- touchwin(gListWin);
- touchwin(gBarWin);
- touchwin(gPromptWin);
- touchwin(gInputWin);
-
- wnoutrefresh(gListWin);
- wnoutrefresh(gBarWin);
- wnoutrefresh(gPromptWin);
- wnoutrefresh(gInputWin);
- }
- doupdate();
- }
- #endif /* USE_CURSES */
- } /* UpdateScreen */
-
-
-
- void FlushListWindow(void)
- {
- #ifdef USE_CURSES
- if (gWinInit) {
- wnoutrefresh(gListWin);
- doupdate();
- return;
- }
- #endif /* USE_CURSES */
- fflush(stdout);
- fflush(stderr); /* Overkill, since stderr _should_ be unbuffered. */
- } /* FlushListWindow */
-
-
-
-
- #ifdef USE_CURSES
- #ifdef SIGTSTP
- static
- void SigTStp(int sigNum)
- {
- /* TO-DO: (doesn't work 100% correctly yet) */
- if (sigNum == SIGTSTP) {
- if ((gPrefsWin != NULL) || (gHostWin != NULL)) {
- /* Doing this with these windows open can cause problems. */
- return;
- }
- SaveScreen();
- TraceMsg("SIGTSTP: Suspended.\n");
- SIGNAL(SIGTSTP, SIG_DFL);
- kill(getpid(), SIGSTOP); /* Send stop signal to ourselves. */
- } else {
- SIGNAL(SIGTSTP, SigTStp);
- SIGNAL(SIGCONT, SigTStp);
- if (sigNum == SIGCONT) {
- TraceMsg("SIGCONT: Resumed.\n");
- } else {
- TraceMsg("SIG %d.\n", sigNum);
- }
- if (InForeGround())
- RestoreScreen(0);
- else
- gBackgroundProcessing = 1;
- }
- } /* SigTStp */
- #endif
- #endif /* USE_CURSES */
-
-
-
-
-
- /* Read a line of input, and axe the end-of-line. */
- char *Gets(char *str, size_t size)
- {
- string pr;
- #ifdef USE_CURSES
- int result;
- WGetsParams wgp;
- int maxy, maxx;
- #endif /* USE_CURSES */
-
- #ifdef USE_CURSES
- if (gWinInit) {
- /* Background processing only gets turned on if you use ^Z
- * from within the program and then "bg" it. We assume that
- * when you do that, you want to get a "tty output" message
- * when the operation finishes. Note that you wouldn't get
- * gBackgroundProcessing == 1 if you did "ncftp &" because
- * you would never get to the part that turns it on (the ^Z
- * handler).
- */
- if (gBackgroundProcessing) {
- /* Want to give you a "stopped - tty output" message in
- * your shell when we get here.
- */
- PrintF("\nBackground processing has finished.\n");
- FlushListWindow();
- while (! InForeGround())
- sleep(1);
- gBackgroundProcessing = 0;
- RestoreScreen(0);
- }
-
- str[0] = '\0';
- wnoutrefresh(gListWin);
- if (gMultiLineMode) {
- SetPrompt(gPrompt);
- gMultiLineMode = 0;
- } else {
- werase(gInputWin);
- wnoutrefresh(gInputWin);
- }
- SetScreenInfo();
- doupdate();
- wgp.w = gInputWin;
- wgp.sy = 0;
- wgp.sx = 0;
-
- getmaxyx(gInputWin, maxy, maxx);
- wgp.fieldLen = maxx - 1;
- wgp.dst = str;
- wgp.dstSize = size;
- wgp.useCurrentContents = 0;
- wgp.echoMode = wg_RegularEcho;
- wgp.history = &gCmdHistory;
- result = wg_Gets(&wgp);
- if (result < 0)
- return (NULL); /* Error, or EOF. */
- return (str);
- } else
- #endif /* USE_CURSES */
- {
- Echo(stdin, 1); /* Turn echo on, if it wasn't already. */
- STRNCPY(pr, gPrompt);
- STRNCAT(pr, kPromptTail);
- return LineModeGets(pr, str, size);
- }
- } /* Gets */
-
-
-
-
- void GetAnswer(char *prompt, char *answer, size_t siz, int noEcho)
- {
- #ifdef USE_CURSES
- WGetsParams wgp;
- int maxy, maxx;
- #endif
-
- PTRZERO(answer, siz);
- #ifdef USE_CURSES
- if (gWinInit) {
- wnoutrefresh(gListWin);
- MakeBottomLine(prompt, kReverse, 0);
- doupdate();
- wgp.w = gInputWin;
- wgp.sy = 0;
- wgp.sx = 0;
- getmaxyx(gInputWin, maxy, maxx);
- wgp.fieldLen = maxx - 1;
- wgp.dst = answer;
- wgp.dstSize = siz;
- wgp.useCurrentContents = 0;
- wgp.echoMode = noEcho ? wg_BulletEcho : wg_RegularEcho;
- wgp.history = wg_NoHistory;
- wg_Gets(&wgp);
- return;
- }
- #endif /* USE_CURSES */
- if (noEcho)
- GetPass(prompt, answer, siz);
- else {
- StdioGets(prompt, answer, siz);
- }
- } /* GetAnswer */
-
-
-
-
- void SetBar(char *l, char *c, char *r, int doUp, int tmpCenter)
- {
- #ifdef USE_CURSES
- int maxy, maxx;
- int i;
- int rmax;
- int llen, rlen, clen;
- string bar;
- string barTmp;
-
- if (gWinInit) {
- if (l == NULL)
- l = gBarLeft;
- else if (doUp != -1)
- STRNCPY(gBarLeft, l);
-
- if (r == NULL)
- r = gBarRight;
- else if (doUp != -1)
- STRNCPY(gBarRight, r);
-
- if (c == NULL) {
- c = gBarCenter;
- /* if (gUsingDefaultBar == 1) {
- *c = '\0';
- gUsingDefaultBar = 0;
- } else */ if (gUsingTmpCenterBar == 1) {
- *c = '\0';
- gUsingTmpCenterBar = 0;
- }
- } else {
- STRNCPY(gBarCenter, c);
- gUsingTmpCenterBar = 0;
- if (tmpCenter)
- gUsingTmpCenterBar = 1;
- }
-
- getmaxyx(gBarWin, maxy, maxx);
- for (i=0; i<maxx; i++)
- bar[i] = ' ';
-
- llen = (int) strlen(l);
- if (llen > maxx - 1)
- llen = maxx - 1;
- rlen = (int) strlen(r);
- if (rlen > maxx - 1)
- rlen = maxx - 1;
- clen = (int) strlen(c);
- if (clen > maxx - 1)
- clen = maxx - 1;
-
- if /* (rlen + (clen/2) > (maxx/2)) */
- ((2*rlen) + (clen) > (maxx))
- {
- /* Put the center part on the left so we can see it. */
- memcpy(bar, c, (size_t) clen);
-
- /* Do the right side. */
- rmax = maxx - 1 - clen;
- if (rmax > 0) {
- AbbrevStr(barTmp, r, (size_t) rmax, 0);
- rmax = strlen(barTmp);
- memcpy(bar + maxx - rmax, r, (size_t) rmax);
- }
- } else {
- /* Do the left side. */
- memcpy(bar, l, (size_t) llen);
-
- /* Do the middle. */
- if (*c != '\0') {
- rlen = maxx - 1;
- AbbrevStr(barTmp, c, (size_t) rlen, 0);
- rlen = strlen(barTmp);
- memcpy(bar + (maxx - 1 - rlen) / 2, barTmp, (size_t) rlen);
- }
-
- /* Do the right side. */
- rmax = maxx - 1 - llen;
- if (rmax > 0) {
- AbbrevStr(barTmp, r, (size_t) rmax, 0);
- rmax = strlen(barTmp);
- memcpy(bar + maxx - rmax, r, (size_t) rmax);
- }
- }
-
- bar[maxx] = '\0';
-
- wmove(gBarWin, 0, 0);
- waddstr(gBarWin, bar);
-
- if (doUp == 0)
- wnoutrefresh(gBarWin);
- else
- wrefresh(gBarWin);
- }
- #endif /* USE_CURSES */
- } /* SetBar */
-
-
-
-
- void SetDefaultBar(void)
- {
- #ifdef USE_CURSES
- string str;
-
- if (gWinInit) {
- STRNCPY(str, "NcFTP ");
- STRNCAT(str, kVersion);
- STRNCAT(str, " by Mike Gleason, NCEMRSoft (mgleason@probe.net).");
- gUsingDefaultBar = 1;
-
- SetBar("", str, "", 0, 0);
- } else {
- SetPrompt(kUseDefaultPrompt);
- }
- #else
- SetPrompt(kUseDefaultPrompt);
- #endif
- } /* SetDefaultBar */
-
-
-
-
- void SetScreenInfo(void)
- {
- string pr;
- string pcwd;
- char *cp;
- int len, len2;
- size_t maxPCwdLen;
-
- MakeStringPrintable(pcwd, (unsigned char *) gRemoteCWD, sizeof(pcwd));
- if (gWinInit) {
- if (gConnected) {
- maxPCwdLen = gScreenWidth - strlen(gRmtInfo.name) - 2;
- AbbrevStr(pr, pcwd, maxPCwdLen, 0);
- SetBar(gRmtInfo.name, NULL, pr, 0, 0);
- SetPrompt(gRmtInfo.bookmarkName);
- } else {
- SetDefaultBar();
- SetPrompt(kUseDefaultPrompt);
- }
- } else {
- if (gConnected) {
- STRNCPY(pr, gRmtInfo.bookmarkName);
- STRNCAT(pr, ":");
- len = (int) strlen(pr);
- len2 = (int) strlen(pcwd);
- if (len + len2 > kPromptLimit) {
- STRNCAT(pr, "...");
- cp = pcwd + len2 - (kPromptLimit - len - 3);
- STRNCAT(pr, cp);
- } else {
- STRNCAT(pr, pcwd);
- }
- SetPrompt(pr);
- } else {
- SetPrompt(kUseDefaultPrompt);
- }
- }
- } /* SetScreenInfo */
-
-
-
-
- #ifdef USE_CURSES
- void PrintToListWindow(char *buf, int multi)
- {
- char *endp, *startp;
- int c, haveNL;
- int haveCR;
- int y, x;
- string pr;
- int extraLines;
-
- if (multi != 0) {
- if (gSkipToEnd == 1)
- return;
- /* Don't wait between pages if they are redialing. We don't
- * want to page the site's connect message if redialing is
- * turned on.
- */
- if (gRedialModeEnabled != 0)
- multi = 0;
- }
-
- endp = buf;
- startp = buf;
-
- while (1) {
- if (*startp == '\0')
- break;
- haveCR = 0;
- haveNL = 0;
- for (endp = startp; ; endp++) {
- if (*endp == '\0') {
- endp = NULL;
- break;
- } else if (*endp == '\n') {
- haveNL = 1;
- *endp = '\0';
- break;
- } else if (*endp == '\r') {
- /* Have to do CRs manually because
- * some systems don't do 'em. (AIX).
- */
- haveCR = 1;
- *endp = '\0';
- break;
- }
- }
-
- /* Take long lines that wrap into account. */
- extraLines = endp == startp ? 0 : (endp - startp - 1) / gScreenWidth;
- gCurRow += extraLines;
- if ((multi) && (gCurRow >= gLastRow) && (!gSkipToEnd) && (!haveCR)) {
- wnoutrefresh(gListWin);
- sprintf(pr, "--Page %d--", (++gPageNum));
- MakeBottomLine(pr, kReverse, 0);
- doupdate();
- cbreak();
- c = mvwgetch(gInputWin, 0, 0);
- nocbreak();
- if (c == 'q') {
- gSkipToEnd = 1;
- gCurRow = 0;
- gPendingNL = 1;
- break;
- }
- gCurRow = extraLines;
- }
-
- if (gPendingNL) {
- waddch(gListWin, '\n');
- }
-
- /* Weird things happened if I did wprintw(gListWin, "%s", startp). */
- waddstr(gListWin, startp);
-
- /* May need to gCurRow++ if line wraps around other side... */
- if (haveNL) {
- gCurRow++;
- } else if (haveCR) {
- getyx(gListWin, y, x);
- wmove(gListWin, y, 0);
- }
- gPendingNL = haveNL;
- if (endp == NULL)
- break;
- startp = endp + 1;
- }
- } /* PrintToListWindow */
- #endif /* USE_CURSES */
-
-
-
-
- /* Prints a message, if you have debbuging mode turned on. */
-
- /*VARARGS*/
- #ifndef HAVE_STDARG_H
- void DebugMsg(va_alist)
- va_dcl
- #else
- void DebugMsg(char *fmt0, ...)
- #endif
- {
- va_list ap;
- char *fmt;
-
- #ifndef HAVE_STDARG_H
- va_start(ap);
- fmt = va_arg(ap, char *);
- #else
- va_start(ap, fmt0);
- fmt = fmt0;
- #endif
-
- if (gDebug == kDebuggingOn) {
- if (gWinInit) {
- #ifdef USE_CURSES
- strcpy(gSprintfBuf, "#DB# ");
- (void) vsprintf(gSprintfBuf + 5, fmt, ap);
- PrintToListWindow(gSprintfBuf, 0);
- #endif /* USE_CURSES */
- } else {
- (void) fprintf(kDebugStream, "#DB# ");
- (void) vfprintf(kDebugStream, fmt, ap);
- (void) fflush(kDebugStream);
- }
- }
- if ((gTrace == kTracingOn) && (gTraceLogFile != NULL)) {
- (void) fprintf(gTraceLogFile, "#DB# ");
- (void) vfprintf(gTraceLogFile, fmt, ap);
- (void) fflush(gTraceLogFile);
- }
- va_end(ap);
- } /* DebugMsg */
-
-
-
-
- /* This is similar to DebugMsg, but only writes to the debug log
- * file. This is useful for putting messages in the log that
- * shouldn't show up on screen (i.e. would make a mess in visual
- * mode.
- */
-
- /*VARARGS*/
- #ifndef HAVE_STDARG_H
- void TraceMsg(va_alist)
- va_dcl
- #else
- void TraceMsg(char *fmt0, ...)
- #endif
- {
- va_list ap;
- char *fmt;
-
- #ifndef HAVE_STDARG_H
- va_start(ap);
- fmt = va_arg(ap, char *);
- #else
- va_start(ap, fmt0);
- fmt = fmt0;
- #endif
-
- if ((gTrace == kTracingOn) && (gTraceLogFile != NULL)) {
- (void) fprintf(gTraceLogFile, "#TR# ");
- (void) vfprintf(gTraceLogFile, fmt, ap);
- (void) fflush(gTraceLogFile);
- }
- va_end(ap);
- } /* TraceMsg */
-
-
-
-
- /* Prints to our own standard output stream. */
-
- /*VARARGS*/
- #ifndef HAVE_STDARG_H
- void PrintF(va_alist)
- va_dcl
- #else
- void PrintF(char *fmt0, ...)
- #endif
- {
- va_list ap;
- char *fmt;
-
- #ifndef HAVE_STDARG_H
- va_start(ap);
- fmt = va_arg(ap, char *);
- #else
- va_start(ap, fmt0);
- fmt = fmt0;
- #endif
-
- /* If it's an important message, don't use this function, use
- * EPrintF() instead.
- */
- if (gVerbosity > kErrorsOnly) {
- if ((gWinInit) && (gRealStdout == gStdout)) {
- #ifdef USE_CURSES
- (void) vsprintf(gSprintfBuf, fmt, ap);
- PrintToListWindow(gSprintfBuf, 0);
- #endif /* USE_CURSES */
- } else {
- (void) vsprintf(gSprintfBuf, fmt, ap);
- (void) write(gStdout, gSprintfBuf, strlen(gSprintfBuf));
- }
- }
- if ((gTrace == kTracingOn) && (gTraceLogFile != NULL)) {
- (void) vfprintf(gTraceLogFile, fmt, ap);
- (void) fflush(gTraceLogFile);
- }
- va_end(ap);
- } /* PrintF */
-
-
-
- /*VARARGS*/
- #ifndef HAVE_STDARG_H
- void BoldPrintF(va_alist)
- va_dcl
- #else
- void BoldPrintF(char *fmt0, ...)
- #endif
- {
- va_list ap;
- char *fmt;
-
- #ifndef HAVE_STDARG_H
- va_start(ap);
- fmt = va_arg(ap, char *);
- #else
- va_start(ap, fmt0);
- fmt = fmt0;
- #endif
-
- if (gVerbosity > kErrorsOnly) {
- if ((gWinInit) && (gRealStdout == gStdout)) {
- #ifdef USE_CURSES
- (void) vsprintf(gSprintfBuf, fmt, ap);
- WAttr(gListWin, kBold, 1);
- PrintToListWindow(gSprintfBuf, 0);
- WAttr(gListWin, kBold, 0);
- #endif /* USE_CURSES */
- } else {
- (void) vsprintf(gSprintfBuf, fmt, ap);
- (void) write(gStdout, gSprintfBuf, strlen(gSprintfBuf));
- }
- }
- if ((gTrace == kTracingOn) && (gTraceLogFile != NULL)) {
- (void) vfprintf(gTraceLogFile, fmt, ap);
- (void) fflush(gTraceLogFile);
- }
- va_end(ap);
- } /* BoldPrintF */
-
-
-
-
- /* Prints to stderr. */
-
- /*VARARGS*/
- #ifndef HAVE_STDARG_H
- void EPrintF(va_alist)
- va_dcl
- #else
- void EPrintF(char *fmt0, ...)
- #endif
- {
- va_list ap;
- char *fmt;
- char *cp;
-
- #ifndef HAVE_STDARG_H
- va_start(ap);
- fmt = va_arg(ap, char *);
- #else
- va_start(ap, fmt0);
- fmt = fmt0;
- #endif
-
- if (gVerbosity > kQuiet) {
- if (gWinInit) {
- #ifdef USE_CURSES
- (void) vsprintf(gSprintfBuf, fmt, ap);
- PrintToListWindow(gSprintfBuf, 0);
-
- /* No buffering on error stream. */
- wnoutrefresh(gListWin);
- doupdate();
- #endif /* USE_CURSES */
- } else {
- (void) vfprintf(stderr, fmt, ap);
- }
- }
- if ((gTrace == kTracingOn) && (gTraceLogFile != NULL)) {
- /* Special hack so when progress meters use \r's we don't
- * print them in the trace file.
- */
- (void) vsprintf(gSprintfBuf, fmt, ap);
- for (cp = gSprintfBuf; ; ) {
- /* Replace all carriage returns with newlines. */
- cp = strchr(cp, '\r');
- if (cp == NULL)
- break;
- *cp++ = '\n';
- }
- fputs(gSprintfBuf, gTraceLogFile);
- (void) fflush(gTraceLogFile);
- }
- va_end(ap);
- } /* EPrintF */
-
-
-
-
-
- /*VARARGS*/
- #ifndef HAVE_STDARG_H
- void Error(va_alist)
- va_dcl
- #else
- void Error(int pError0, char *fmt0, ...)
- #endif
- {
- va_list ap;
- char *fmt;
- int pError;
- longstring buf2;
-
- #ifndef HAVE_STDARG_H
- va_start(ap);
- pError = va_arg(ap, int);
- fmt = va_arg(ap, char *);
- #else
- va_start(ap, fmt0);
- fmt = fmt0;
- pError = pError0;
- #endif
-
- if (gVerbosity > kQuiet) {
- if (gWinInit) {
- #ifdef USE_CURSES
- (void) vsprintf(gSprintfBuf, fmt, ap);
- if (gDebug == kDebuggingOn)
- sprintf(buf2, "Error(%d): ", errno);
- else
- STRNCPY(buf2, "Error: ");
- STRNCAT(buf2, gSprintfBuf);
- #ifdef HAVE_STRERROR
- if ((pError == kDoPerror) && (errno > 0)) {
- STRNCAT(buf2, "Reason: ");
- STRNCAT(buf2, strerror(errno));
- STRNCAT(buf2, "\n");
- }
- #endif /* HAVE_STRERROR */
- PrintToListWindow(buf2, 0);
- #endif /* USE_CURSES */
- } else {
- (void) fprintf(stderr, "Error");
- if (gDebug == kDebuggingOn)
- (void) fprintf(stderr, "(%d)", errno);
- (void) fprintf(stderr, ": ");
- (void) vfprintf(stderr, fmt, ap);
- (void) fflush(stderr);
- if ((pError == kDoPerror) && (errno > 0))
- perror("Reason");
- }
- }
- if ((gTrace == kTracingOn) && (gTraceLogFile != NULL)) {
- (void) fprintf(gTraceLogFile, "Error(%d): ", errno);
- (void) vfprintf(gTraceLogFile, fmt, ap);
- #ifdef HAVE_STRERROR
- if ((pError == kDoPerror) && (errno > 0))
- (void) fprintf(gTraceLogFile, "Reason: %s\n", strerror(errno));
- #endif
- (void) fflush(gTraceLogFile);
- }
- va_end(ap);
- } /* Error */
-
-
-
-
- void MultiLineInit(void)
- {
- #ifdef USE_CURSES
- int maxy, maxx;
-
- if (gWinInit) {
- gCurRow = 0;
- getmaxyx(gListWin, maxy, maxx);
- gLastRow = maxy;
- gSkipToEnd = 0;
- gPageNum = 0;
- gMultiLineMode = 1;
- }
- #endif /* USE_CURSES */
- } /* MultiLineInit */
-
-
-
- /*VARARGS*/
- #ifndef HAVE_STDARG_H
- void MultiLinePrintF(va_alist)
- va_dcl
- #else
- void MultiLinePrintF(char *fmt0, ...)
- #endif
- {
- va_list ap;
- char *fmt;
-
- #ifndef HAVE_STDARG_H
- va_start(ap);
- fmt = va_arg(ap, char *);
- #else
- va_start(ap, fmt0);
- fmt = fmt0;
- #endif
-
- if (gVerbosity > kErrorsOnly) {
- if ((gWinInit) && (gRealStdout == gStdout)) {
- #ifdef USE_CURSES
- (void) vsprintf(gSprintfBuf, fmt, ap);
- PrintToListWindow(gSprintfBuf, 1);
- #endif /* USE_CURSES */
- } else {
- (void) vsprintf(gSprintfBuf, fmt, ap);
- (void) write(gStdout, gSprintfBuf, strlen(gSprintfBuf));
- }
- }
- if ((gTrace == kTracingOn) && (gTraceLogFile != NULL)) {
- (void) vfprintf(gTraceLogFile, fmt, ap);
- (void) fflush(gTraceLogFile);
- }
-
- va_end(ap);
- } /* MultiLinePrintF */
-
-
-
-
- void MakeBottomLine(char *pr, int flags, int addTail)
- {
- #ifdef USE_CURSES
- int len;
- int doCreate;
- int maxy, maxx;
-
- len = (int) strlen(pr);
- if (addTail)
- len += strlen(kPromptTail);
- else if (flags & kReverse)
- len++; /* Will add a space so you can see cursor. */
-
- doCreate = 0;
- if (gPromptWin != NULL) {
- getmaxyx(gPromptWin, maxy, maxx);
- if (maxx != len) {
- delwin(gPromptWin);
- delwin(gInputWin);
- doCreate = 1;
- }
- } else {
- doCreate = 1;
- }
-
- if (doCreate) {
- gPromptWin = newwin(1, len, LINES - 1, 0);
- gInputWin = newwin(1, COLS - len, LINES - 1, len);
-
- if ((gPromptWin == NULL) || (gInputWin == NULL))
- Exit(kExitWinFail2);
- }
-
- werase(gPromptWin);
- WAttr(gPromptWin, flags, 1);
- if (addTail) {
- mvwprintw(gPromptWin, 0,0, "%s%s", pr, kPromptTail);
- WAttr(gPromptWin, flags, 0);
- } else {
- mvwprintw(gPromptWin, 0,0, "%s", pr);
- WAttr(gPromptWin, flags, 0);
- }
- wnoutrefresh(gPromptWin);
- werase(gInputWin);
- touchwin(gInputWin);
- wnoutrefresh(gInputWin);
- doupdate();
- #endif /* USE_CURSES */
- } /* MakeBottomLine */
-
-
-
-
- void SetPrompt(char *pr)
- {
- string p;
-
- if ((pr == kUseDefaultPrompt)
- || STREQ(pr, kLineModePrompt)
- || STREQ(pr, kVisualModePrompt)) {
- if (gWinInit)
- STRNCPY(p, kVisualModePrompt);
- else
- STRNCPY(p, kLineModePrompt);
- } else {
- STRNCPY(p, pr);
- }
- STRNCPY(gPrompt, p);
- #ifdef USE_CURSES
- if (gWinInit)
- MakeBottomLine(p, kBold, 1);
- #endif /* USE_CURSES */
- } /* SetPrompt */
-
-
-
- #ifdef USE_CURSES
- /* Draws a string centered in a window. */
- void WAddCenteredStr(WINDOW *w, int y, char *str)
- {
- int x;
- int maxy, maxx;
-
- getmaxyx(w, maxy, maxx);
- x = (maxx - strlen(str)) / 2;
- if (x < 0)
- x = 0;
- wmove(w, y, x);
- waddstr(w, str);
- } /* WAddCenteredStr */
- #endif /* USE_CURSES */
-
-
-
-
- void InitWindows(void)
- {
- char *cp;
- int on;
- #ifdef USE_CURSES
- int maxx, maxy;
- #endif
-
- on = gVisualMode && gIsToTTY && gIsFromTTY;
-
- #ifdef USE_CURSES
- if (on) {
- initscr();
- if (stdscr == NULL)
- goto fail;
- gWinInit = 1;
- SIGNAL(SIGTERM, SigTerm);
-
- nl();
-
- gPromptWin = gInputWin = NULL;
- gListWin = newwin(LINES - 2, COLS, 0, 0);
- gBarWin = newwin(1, COLS, LINES - 2, 0);
-
- if ((gListWin == NULL) || (gBarWin == NULL))
- Exit(kExitWinFail1);
-
- scrollok(gListWin, TRUE);
- idlok(gListWin, TRUE);
- wmove(gListWin, 0, 0);
- noecho(); /* Leave this off until we need it. */
-
- WAttr(gBarWin, kReverse, 1);
-
- getmaxyx(gListWin, maxy, maxx);
- gScreenWidth = maxx;
-
- gBarLeft[0] = '\0';
- gBarCenter[0] = '\0';
- gBarRight[0] = '\0';
-
- LoadHistory();
-
- /* Probably not set yet, unless you specified a host on
- * the command line.
- */
- SetScreenInfo();
- #ifdef SIGTSTP
- if (SIGNAL(SIGTSTP, SIG_IGN) != SIG_IGN) {
- SIGNAL(SIGTSTP, SigTStp);
- SIGNAL(SIGCONT, SigTStp);
- }
- #endif
- return;
- }
- fail:
- #endif /* USE_CURSES */
- gWinInit = 0;
-
- cp = (char *) getenv("COLUMNS");
- if (cp != NULL)
- gScreenWidth = atoi(cp);
-
- /* Prompt will already be set if connected. */
- if (gConnected == 0)
- SetPrompt(kUseDefaultPrompt);
- } /* InitWindows */
-
- /* eof */
-
-