/* Prompts for an integer of input. */ void EditHostWinGetNum(int *dst) { WGetsParams wgp; char str[256]; int maxy, maxx; getmaxyx(gEditHostWin, maxy, maxx); WAttr(gEditHostWin, kBold, 1); DrawStrAt(gEditHostWin, maxy - 1, 0, "> "); WAttr(gEditHostWin, kBold, 0); wclrtoeol(gEditHostWin); wrefresh(gEditHostWin); curs_set(1); wgp.w = gEditHostWin; wgp.sy = maxy - 1; wgp.sx = 2; wgp.fieldLen = maxx - 3; wgp.dst = str; wgp.dstSize = sizeof(str); wgp.useCurrentContents = 0; wgp.echoMode = wg_RegularEcho; wgp.history = wg_NoHistory; (void) wg_Gets(&wgp); cbreak(); /* wg_Gets turns off cbreak and delay. */ AtoIMaybe(dst, str); wmove(gEditHostWin, maxy - 1, 0); wclrtoeol(gEditHostWin); wrefresh(gEditHostWin); curs_set(0); } /* EditHostWinGetNum */
/* Prompts for a line of input. */ void EditHostWinGetStr(char *dst, size_t size, int canBeEmpty, int canEcho) { char str[256]; WGetsParams wgp; int maxy, maxx; WAttr(gEditHostWin, kBold, 1); getmaxyx(gEditHostWin, maxy, maxx); DrawStrAt(gEditHostWin, maxy - 1, 0, "> "); WAttr(gEditHostWin, kBold, 0); wclrtoeol(gEditHostWin); wrefresh(gEditHostWin); curs_set(1); wgp.w = gEditHostWin; wgp.sy = maxy - 1; wgp.sx = 2; wgp.fieldLen = maxx - 3; wgp.dst = str; wgp.dstSize = size; wgp.useCurrentContents = 0; wgp.echoMode = canEcho ? wg_RegularEcho : wg_BulletEcho; wgp.history = wg_NoHistory; (void) wg_Gets(&wgp); cbreak(); /* wg_Gets turns off cbreak and delay. */ /* See if the user just hit return. We may not want to overwrite * the dst here, which would make it an empty string. */ if ((wgp.changed) || (canBeEmpty == kOkayIfEmpty)) strcpy(dst, str); wmove(gEditHostWin, maxy - 1, 0); wclrtoeol(gEditHostWin); wrefresh(gEditHostWin); curs_set(0); } /* EditHostWinGetStr */
/* This one is the brainchild of my comrade, Phil Dietz. It shows the * progress as a fancy bar graph. */ int PrPhilBar(XferSpecPtr xp, int mode) { int result = kPrWantStatsMsg; int perc; long s; int curBarLen; static int maxBarLen; str64 spec1, spec3; static string bar; int i; int secsLeft, minLeft; switch (mode) { case kPrInitMsg: EPrintF("%s file: %s \n", NETREADING(xp) ? "Receiving" : "Sending", xp->localFileName ); for (i=0; i < (int) sizeof(bar) - 1; i++) bar[i] = '='; bar[i] = '\0'; /* Compute the size of the bar itself. This sits between * two numbers, one on each side of the screen. So the * bar length will vary, depending on how many digits we * need to display the size of the file. */ maxBarLen = gScreenWidth - 1 - 28; for (s = xp->expectedSize; s > 0; s /= 10L) maxBarLen--; /* Create a specification we can hand to printf. */ (void) sprintf(spec1, " 0 %%%ds %%ld bytes. ETA: --:--", maxBarLen); /* Print the first invocation, which is an empty graph * plus the other stuff. */ EPrintF(spec1, " ", xp->expectedSize); break; case kPrUpdateMsg: /* Compute how much of the bar should be colored in. */ curBarLen = (int) (xp->frac * (double)maxBarLen); /* Colored portion must be at least one character so * the spec isn't '%0s' which would screw the right side * of the indicator. */ if (curBarLen < 1) curBarLen = 1; bar[curBarLen - 1] = '>'; bar[curBarLen] = '\0'; /* Make the spec, so we can print the bar and the other stuff. */ STRNCPY(spec1, "\r%3d%% 0 "); (void) sprintf(spec3, "%%%ds %%ld bytes. %s%%3d:%%02d", maxBarLen - curBarLen, "ETA:" ); /* We also show the percentage as a number at the left side. */ perc = (int) (100.0 * xp->frac); /* Guess how much time is remaining in the transfer, based on * the current transfer statistics. */ secsLeft = (int) ((xp->bytesLeft / xp->bytesPerSec) + 0.5); minLeft = secsLeft / 60; secsLeft = secsLeft - (minLeft * 60); if (minLeft > 999) { minLeft = 999; secsLeft = 59; } /* Print the updated information. */ #ifdef USE_CURSES if (gWinInit) { EPrintF(spec1, perc); WAttr(gListWin, kReverse, 1); EPrintF("%s", bar); WAttr(gListWin, kReverse, 0); EPrintF(spec3, "", xp->expectedSize, minLeft, secsLeft ); } else #endif /* USE_CURSES */ { EPrintF(spec1, perc); EPrintF("%s", bar); EPrintF(spec3, "", xp->expectedSize, minLeft, secsLeft ); } bar[curBarLen - 1] = '='; bar[curBarLen] = '='; break; case kPrEndMsg: result = kPrWantStatsMsg; EPrintF("\n"); break; } return result; } /* PrPhilBar */
/* This opens and handles the site options window. */ void HostWinEdit(void) { int c, field; int needUpdate; char bmname[128]; BookmarkPtr rsip; if (gCurHostListItem != NULL) { gEditHostWin = newwin(LINES, COLS, 0, 0); if (gEditHostWin == NULL) return; STRNCPY(bmname, gCurHostListItem->bookmarkName); /* Set the clear flag for the first update. */ wclear(gEditHostWin); /* leaveok(gEditHostWin, TRUE); * Not sure if I like this... */ WAttr(gEditHostWin, kBold, 1); WAddCenteredStr(gEditHostWin, 0, "Bookmark Options"); WAttr(gEditHostWin, kBold, 0); /* We'll be editing a copy of the current host's settings. */ gEditRsi = *gCurHostListItem; EditHostWinDraw(kAllWindowItems, kNoHilite); field = 1; for (;;) { EditHostWinMsg("Select an item to edit by typing its corresponding letter."); c = wgetch(gEditHostWin); if (islower(c)) c = toupper(c); if (!isupper(c)) continue; if (c == 'X') break; field = c - 'A'; needUpdate = 1; /* Hilite the current item to edit. */ EditHostWinDraw(BIT(field), kHilite); switch(field) { case kNicknameEditWindowItem: EditHostWinMsg("Type a new bookmark name, or hit <RETURN> to continue."); EditHostWinGetStr(gEditRsi.bookmarkName, sizeof(gEditRsi.bookmarkName), kNotOkayIfEmpty, kGetAndEcho); break; case kHostnameEditWindowItem: EditHostWinMsg("Type a new hostname, or hit <RETURN> to continue."); EditHostWinGetStr(gEditRsi.name, sizeof(gEditRsi.name), kNotOkayIfEmpty, kGetAndEcho); gEditRsi.lastIP[0] = '\0'; /* In case it changed. */ break; case kUserEditWindowItem: EditHostWinMsg("Type a username, or hit <RETURN> to signify anonymous."); EditHostWinGetStr(gEditRsi.user, sizeof(gEditRsi.user), kOkayIfEmpty, kGetAndEcho); break; case kPassEditWindowItem: EditHostWinMsg("Type a password, or hit <RETURN> if no password is required."); EditHostWinGetStr(gEditRsi.pass, sizeof(gEditRsi.pass), kOkayIfEmpty, kGetNoEcho); break; case kAcctEditWindowItem: EditHostWinMsg("Type an account name, or hit <RETURN> if no account is required."); EditHostWinGetStr(gEditRsi.acct, sizeof(gEditRsi.acct), kOkayIfEmpty, kGetAndEcho); break; case kDirEditWindowItem: EditHostWinMsg("Type a remote directory path to start in after a connection is established."); EditHostWinGetStr(gEditRsi.dir, sizeof(gEditRsi.dir), kOkayIfEmpty, kGetAndEcho); break; case kLDirEditWindowItem: EditHostWinMsg("Type a local directory path to start in after a connection is established."); EditHostWinGetStr(gEditRsi.ldir, sizeof(gEditRsi.ldir), kOkayIfEmpty, kGetAndEcho); break; case kXferTypeEditWindowItem: EditHostWinMsg(kToggleMsg); ToggleXferType(); break; case kPortEditWindowItem: EditHostWinMsg("Type a port number to use for FTP."); EditHostWinGetNum((int *) &gEditRsi.port); break; #if 0 case kSizeEditWindowItem: EditHostWinMsg(kToggleMsg); EditWinToggle(&gEditRsi.hasSIZE, field, 0, 1); break; case kMdtmEditWindowItem: EditHostWinMsg(kToggleMsg); EditWinToggle(&gEditRsi.hasMDTM, field, 0, 1); break; case kPasvEditWindowItem: EditHostWinMsg(kToggleMsg); EditWinToggle(&gEditRsi.hasPASV, field, 0, 1); break; case kOSEditWindowItem: EditHostWinMsg(kToggleMsg); EditWinToggle(&gEditRsi.isUnix, field, 0, 1); break; #endif case kCommentEditWindowItem: EditHostWinMsg("Enter a line of information to store about this site."); EditHostWinGetStr(gEditRsi.comment, sizeof(gEditRsi.comment), kOkayIfEmpty, kGetAndEcho); break; default: needUpdate = 0; break; } if (needUpdate) EditHostWinDraw(BIT(field), kNoHilite); } delwin(gEditHostWin); gEditHostWin = NULL; *gCurHostListItem = gEditRsi; SaveAndReload(); /* Note: newly reallocated array, modified gNumBookmarks */ rsip = SearchBookmarkTable(bmname); if (rsip == NULL) rsip = &gBookmarkTable[0]; gCurHostListItem = rsip; gHilitedHost = BMTINDEX(rsip); gHostListWinStart = BMTINDEX(rsip) - gHostListPageSize + 1; if (gHostListWinStart < 0) gHostListWinStart = 0; UpdateHostWindows(1); } } /* HostWinEdit */
/* This is the meat of the site options window. We can selectively update * portions of the window by using a bitmask with bits set for items * we want to update. */ void EditHostWinDraw(int flags, int hilite) { int maxy, maxx; int i, f; char str[256]; char spec[32]; const char *cp; /* Draw the keys the user can type in reverse text. */ WAttr(gEditHostWin, kReverse, 1); f = 5; for (i = kFirstEditWindowItem; i <= kLastEditWindowItem; i++) { if (TESTBIT(flags, i)) mvwaddch(gEditHostWin, f + i, 2, 'A' + i); } /* The "quit" item is a special item that is offset a line, and * always has the "X" key assigned to it. */ i = kQuitEditWindowItem; if (TESTBIT(flags, i)) mvwaddch(gEditHostWin, 1 + f + i, 2, 'X'); WAttr(gEditHostWin, kReverse, 0); /* We can use this to hilite a whole line, to indicate to the * user that a certain item is being edited. */ if (hilite) WAttr(gEditHostWin, kReverse, 1); getmaxyx(gEditHostWin, maxy, maxx); sprintf(spec, " %%-26s%%-%ds", maxx - 32); /* Now draw the items on a case-by-case basis. */ if (TESTBIT(flags, kNicknameEditWindowItem)) { mvwprintw(gEditHostWin, kNicknameEditWindowItem + f, 3, spec, "Bookmark name:", gEditRsi.bookmarkName ); wclrtoeol(gEditHostWin); } if (TESTBIT(flags, kHostnameEditWindowItem)) { mvwprintw(gEditHostWin, kHostnameEditWindowItem + f, 3, spec, "Hostname:", gEditRsi.name ); wclrtoeol(gEditHostWin); } if (TESTBIT(flags, kUserEditWindowItem)) { mvwprintw(gEditHostWin, kUserEditWindowItem + f, 3, spec, "User:"******"anonymous" : gEditRsi.user ); wclrtoeol(gEditHostWin); } if (TESTBIT(flags, kPassEditWindowItem)) { if (gEditRsi.pass[0] == '\0' && gEditRsi.user[0] == '\0') STRNCPY(str, gLib.defaultAnonPassword); mvwprintw(gEditHostWin, kPassEditWindowItem + f, 3, spec, "Password:"******"********" : str ); wclrtoeol(gEditHostWin); } if (TESTBIT(flags, kAcctEditWindowItem)) { mvwprintw(gEditHostWin, kAcctEditWindowItem + f, 3, spec, "Account:", gEditRsi.acct[0] == '\0' ? "none" : gEditRsi.acct ); wclrtoeol(gEditHostWin); } if (TESTBIT(flags, kDirEditWindowItem)) { if (gEditRsi.dir[0] == '\0') STRNCPY(str, "/"); else AbbrevStr(str, gEditRsi.dir, (size_t) maxx - 32, 0); mvwprintw(gEditHostWin, kDirEditWindowItem + f, 3, spec, "Remote Directory:", str ); wclrtoeol(gEditHostWin); } if (TESTBIT(flags, kLDirEditWindowItem)) { if (gEditRsi.ldir[0] == '\0') STRNCPY(str, "(current)"); else AbbrevStr(str, gEditRsi.ldir, (size_t) maxx - 32, 0); mvwprintw(gEditHostWin, kLDirEditWindowItem + f, 3, spec, "Local Directory:", str ); wclrtoeol(gEditHostWin); } if (TESTBIT(flags, kXferTypeEditWindowItem)) { if ((gEditRsi.xferType == 'I') || (gEditRsi.xferType == 'B')) cp = "Binary"; else if (gEditRsi.xferType == 'A') cp = "ASCII Text"; else cp = "Tenex"; mvwprintw(gEditHostWin, kXferTypeEditWindowItem + f, 3, spec, "Transfer type:", cp ); wclrtoeol(gEditHostWin); } if (TESTBIT(flags, kPortEditWindowItem)) { sprintf(str, "%u", (gEditRsi.port == 0) ? 21 : (unsigned int) gEditRsi.port); mvwprintw(gEditHostWin, kPortEditWindowItem + f, 3, spec, "Port:", str ); wclrtoeol(gEditHostWin); } #if 0 if (TESTBIT(flags, kSizeEditWindowItem)) { mvwprintw(gEditHostWin, kSizeEditWindowItem + f, 3, spec, "Has SIZE command:", gEditRsi.hasSIZE ? "Yes" : "No" ); wclrtoeol(gEditHostWin); } if (TESTBIT(flags, kMdtmEditWindowItem)) { mvwprintw(gEditHostWin, kMdtmEditWindowItem + f, 3, spec, "Has MDTM command:", gEditRsi.hasMDTM ? "Yes" : "No" ); wclrtoeol(gEditHostWin); } if (TESTBIT(flags, kPasvEditWindowItem)) { mvwprintw(gEditHostWin, kPasvEditWindowItem + f, 3, spec, "Can use passive FTP:", gEditRsi.hasPASV ? "Yes" : "No" ); wclrtoeol(gEditHostWin); } if (TESTBIT(flags, kOSEditWindowItem)) { mvwprintw(gEditHostWin, kOSEditWindowItem + f, 3, spec, "Operating System:", (gEditRsi.isUnix == 1) ? "UNIX" : "Non-UNIX" ); wclrtoeol(gEditHostWin); } #endif if (TESTBIT(flags, kCommentEditWindowItem)) { if (gEditRsi.comment[0] == '\0') STRNCPY(str, "(none)"); else AbbrevStr(str, gEditRsi.comment, (size_t) maxx - 32, 0); mvwprintw(gEditHostWin, kCommentEditWindowItem + f, 3, spec, "Comment:", str ); wclrtoeol(gEditHostWin); } if (TESTBIT(flags, kQuitEditWindowItem)) { mvwprintw(gEditHostWin, kQuitEditWindowItem + f + 1, 3, spec, "(Done editing)", "" ); wclrtoeol(gEditHostWin); } if (hilite) WAttr(gEditHostWin, kReverse, 0); wmove(gEditHostWin, maxy - 1, 0); wrefresh(gEditHostWin); } /* EditHostWinDraw */
/* This draws the scrolling list of bookmarks, and hilites the currently * selected host. */ void DrawHostList(void) { int lastLine, i; BookmarkPtr rsip; char str[256]; char url[256]; int maxy, maxx; int lmaxy, lmaxx; int begy, begx; char spec[32]; getmaxyx(gHostListWin, lmaxy, lmaxx); getbegyx(gHostListWin, begy, begx); getmaxyx(gHostWin, maxy, maxx); /* We have a status line saying how many bookmarks there are in * the list. That way the user knows something is supposed to * be there when the host list is totally empty, and also that * there are more bookmarks to look at when the entire host list * doesn't fit in the scroll window. */ WAttr(gHostWin, kUnderline, 1); mvwprintw( gHostWin, begy - 1, begx, strcpy(spec, "%s"), /* avoid warnings on BSD */ "Number of bookmarks" ); WAttr(gHostWin, kUnderline, 0); wprintw( gHostWin, strcpy(spec, ": %3d"), gNumBookmarks ); if (gHostListWinWide == 0) { sprintf(spec, "%%-16.16s %%-%ds", lmaxx - 17); lastLine = lmaxy + gHostListWinStart; for (i=gHostListWinStart; (i<lastLine) && (i<gNumBookmarks); i++) { rsip = &gBookmarkTable[i]; if (rsip == gCurHostListItem) WAttr(gHostListWin, kReverse, 1); sprintf(str, spec, rsip->bookmarkName, rsip->name); str[lmaxx] = '\0'; DrawStrAt(gHostListWin, i - gHostListWinStart, 0, str); swclrtoeol(gHostListWin); if (rsip == gCurHostListItem) { WAttr(gHostListWin, kReverse, 0); } } } else { lastLine = lmaxy + gHostListWinStart; for (i=gHostListWinStart; (i<lastLine) && (i<gNumBookmarks); i++) { rsip = &gBookmarkTable[i]; if (rsip == gCurHostListItem) WAttr(gHostListWin, kReverse, 1); BookmarkToURL(rsip, url, sizeof(url)); sprintf(str, "%-16.16s ", rsip->bookmarkName); STRNCAT(str, url); memset(url, 0, sizeof(url)); AbbrevStr(url, str, (size_t) lmaxx, 1); DrawStrAt(gHostListWin, i - gHostListWinStart, 0, url); swclrtoeol(gHostListWin); if (rsip == gCurHostListItem) { WAttr(gHostListWin, kReverse, 0); } } } /* Add 'vi' style empty-lines. */ for ( ; i<lastLine; ++i) { DrawStrAt(gHostListWin, i - gHostListWinStart, 0, "~"); swclrtoeol(gHostListWin); } wmove(gHostWin, maxy - 3, 2); sprintf(spec, "%%-%ds", maxx - 4); if (gCurHostListItem == NULL) { str[0] = '\0'; } else if (gCurHostListItem->comment[0] == '\0') { memset(str, 0, sizeof(str)); if (gHostListWinWide == 0) { BookmarkToURL(gCurHostListItem, url, sizeof(url)); AbbrevStr(str, url, (size_t) maxx - 2, 1); } } else { STRNCPY(str, "``"); STRNCAT(str, gCurHostListItem->comment); AbbrevStr(str + 2, gCurHostListItem->comment, (size_t) maxx - 8, 1); STRNCAT(str, "''"); } wprintw(gHostWin, spec, str); wmove(gHostWin, maxy - 1, 0); UpdateHostWindows(0); } /* DrawHostList */
/* Runs the host editor. Another big use for this is to open sites * that are in your host list. */ int HostWindow(void) { int c; char cmd[256]; volatile BookmarkPtr toOpen; vsigproc_t si; int maxy, maxx; int lmaxy; si = (sigproc_t) (-1); if (gWinInit) { gHostListWin = NULL; gHostWin = NULL; gHostWin = newwin(LINES, COLS, 0, 0); if (gHostWin == NULL) return (-1); curs_set(0); cbreak(); /* Set the clear flag for the first update. */ wclear(gHostWin); keypad(gHostWin, TRUE); /* For arrow keys. */ #ifdef HAVE_NOTIMEOUT notimeout(gHostWin, TRUE); #endif #ifdef HAVE_SIGSETJMP if (sigsetjmp(gHostWinJmp, 1) == 0) { #else /* HAVE_SIGSETJMP */ if (setjmp(gHostWinJmp) == 0) { #endif /* HAVE_SIGSETJMP */ /* Gracefully cleanup the screen if the user ^C's. */ si = NcSignal(SIGINT, SigIntHostWin); /* Initialize the page start and select a host to be * the current one. */ gHostListWinStart = 0; gHilitedHost = 0; if (gNumBookmarks == 0) gCurHostListItem = NULL; else gCurHostListItem = &gBookmarkTable[gHilitedHost]; /* Initially, we don't want to connect to any site in * the host list. */ toOpen = NULL; getmaxyx(gHostWin, maxy, maxx); WAttr(gHostWin, kBold, 1); WAddCenteredStr(gHostWin, 0, "NcFTP Bookmark Editor"); WAttr(gHostWin, kBold, 0); DrawStrAt(gHostWin, 3, 2, "Open selected site: <enter>"); DrawStrAt(gHostWin, 4, 2, "Edit selected site: /ed"); DrawStrAt(gHostWin, 5, 2, "Delete selected site: /del"); DrawStrAt(gHostWin, 6, 2, "Duplicate selected site: /dup"); DrawStrAt(gHostWin, 7, 2, "Add a new site: /new"); DrawStrAt(gHostWin, 9, 2, "Up one: <u>"); DrawStrAt(gHostWin, 10, 2, "Down one: <d>"); DrawStrAt(gHostWin, 11, 2, "Previous page: <p>"); DrawStrAt(gHostWin, 12, 2, "Next page: <n>"); DrawStrAt(gHostWin, 14, 2, "Capital letters selects first"); DrawStrAt(gHostWin, 15, 2, " site starting with the letter."); DrawStrAt(gHostWin, 17, 2, "Exit the bookmark editor: <x>"); /* Initialize the scrolling host list window. */ if (maxx < 110) { gHostListWinWide = 0; gHostListWin = subwin( gHostWin, LINES - 7, 40, 3, COLS - 40 - 2 ); } else { gHostListWinWide = COLS - 42; gHostListWin = subwin( gHostWin, LINES - 7, gHostListWinWide, 3, 38 ); } if (gHostListWin == NULL) return (-1); lmaxy = getmaxy(gHostListWin); gHostListPageSize = lmaxy; DrawHostList(); wmove(gHostWin, maxy - 1, 0); UpdateHostWindows(1); for (;;) { c = HostWinGetKey(); if (gNeedToClearMsg) { wmove(gHostWin, maxy - 2, 0); wclrtoeol(gHostWin); wrefresh(gHostWin); } if ((c >= 'A') && (c <= 'Z')) { /* isupper can coredump if wgetch returns a meta key. */ HostWinZoomTo(c); } else if (c == '/') { /* Get an "extended" command. Sort of like vi's * :colon commands. */ HostWinGetStr(cmd, sizeof(cmd)); if (ISTREQ(cmd, "ed")) HostWinEdit(); else if (ISTREQ(cmd, "dup")) HostWinDup(); else if (ISTREQ(cmd, "del")) HostWinDelete(); else if (ISTREQ(cmd, "new")) HostWinNew(); else HostWinMsg("Invalid bookmark editor command."); } else switch(c) { case 10: /* ^J == newline */ goto enter; case 13: /* ^M == carriage return */ goto enter; #ifdef KEY_ENTER case KEY_ENTER: Trace(1, " [0x%04X, %s]\n", c, "ENTER"); #endif enter: if (gCurHostListItem == NULL) HostWinMsg("Nothing to open. Try 'open sitename' from the main screen."); else { toOpen = (BookmarkPtr) gCurHostListItem; goto done; } break; case kControl_L: UpdateHostWindows(1); break; case 'u': case 'k': /* vi up key */ case 'h': /* vi left key */ HostListLineUp(); break; #ifdef KEY_UP case KEY_UP: Trace(1, " [0x%04X, %s]\n", c, "UP"); HostListLineUp(); break; #endif #ifdef KEY_LEFT case KEY_LEFT: Trace(1, " [0x%04X, %s]\n", c, "LEFT"); HostListLineUp(); break; #endif case 'd': case 'j': /* vi down key */ case 'l': /* vi right key */ HostListLineDown(); break; #ifdef KEY_DOWN case KEY_DOWN: Trace(1, " [0x%04X, %s]\n", c, "DOWN"); HostListLineDown(); break; #endif #ifdef KEY_RIGHT case KEY_RIGHT: Trace(1, " [0x%04X, %s]\n", c, "RIGHT"); HostListLineDown(); break; #endif case 'p': HostListPageUp(); break; #ifdef KEY_PPAGE case KEY_PPAGE: Trace(1, " [0x%04X, %s]\n", c, "PPAGE"); HostListPageUp(); break; #endif case 'n': HostListPageDown(); break; #ifdef KEY_NPAGE case KEY_NPAGE: Trace(1, " [0x%04X, %s]\n", c, "NPAGE"); HostListPageDown(); break; #endif case 'x': case 'q': goto done; default: HostWinMsg("Invalid key."); Trace(1, " [0x%04X, %s]\n", c, "<invalid>"); break; } } } NcSignal(SIGINT, (FTPSigProc) SIG_IGN); done: if (gHostListWin != NULL) delwin(gHostListWin); if (gHostWin != NULL) delwin(gHostWin); gHostListWin = gHostWin = NULL; if (si != (sigproc_t) (-1)) NcSignal(SIGINT, si); if (toOpen != (BookmarkPtr) 0) { /* If the user selected a site to open, connect to it now. */ if (gStandAlone != 0) { LaunchNcFTP(toOpen->bookmarkName); /*NOTREACHED*/ Exit(0); } else if (gBookmarkSelectionFile != NULL) { WriteSelectedBMToFile(toOpen->bookmarkName); } return (kNoErr); } } return (kNoErr); } /* HostWindow */ main_void_return_t main(int argc, const char **argv) { int result; int argi; gStandAlone = 1; gBookmarkSelectionFile = NULL; InitUserInfo(); if (LoadBookmarkTable() < 0) { exit(7); } if (argc > 1) { /* The following hack is used by NcFTP * to get the number of columns without * having to link with curses/termcap. * This simplifies things since the * system may or may not have a good * curses implementation, and we don't * want to complicate NcFTP itself with * that. */ argi = 1; if (strcmp(argv[1], "--dimensions") == 0) { result = PrintDimensions(0); exit((result == 0) ? 0 : 1); } else if (strcmp(argv[1], "--dimensions-terse") == 0) { result = PrintDimensions(1); exit((result == 0) ? 0 : 1); } else if (strcmp(argv[1], "--debug") == 0) { SetDebug(1); argi++; } /* Requested that we were run from ncftp. */ gStandAlone = 0; if ((argc > argi) && (argv[argi][0] == '/')) gBookmarkSelectionFile = (const char *) argv[argi]; if (gNumBookmarks < 1) exit(7); } result = FTPInitLibrary(&gLib); if (result < 0) { (void) fprintf(stderr, "ncftp: init library error %d (%s).\n", result, FTPStrError(result)); exit(1); } result = FTPInitConnectionInfo(&gLib, &gConn, kDefaultFTPBufSize); if (result < 0) { (void) fprintf(stderr, "ncftp: init connection info error %d (%s).\n", result, FTPStrError(result)); exit(1); } if (gDebug > 0) OpenTrace(); InitPrefs(); LoadFirewallPrefs(0); LoadPrefs(); InitWindows(); Trace(1, "Terminal size is %d columns by %d rows.\n", gScreenWidth, gScreenHeight); HostWindow(); if (gDebug > 0) CloseTrace(); EndWin(); exit(0); } /* main */
static void et_inittextmode(struct ite_softc *ip, et_sv_reg_t *etregs, int loadfont) { volatile u_char *ba; font_info *fd; u_char *fb; u_char *c, *f, tmp; u_short z, y; int s; view_t *v = viewview(ip->grf->g_viewdev); et_sv_reg_t loc_regs; if (etregs == NULL) { etregs = &loc_regs; et_hwsave(etregs); } ba = ((ipriv_t*)ip->priv)->regkva; fb = v->bitmap->plane; #if defined(KFONT_8X8) fd = &font_info_8x8; #else fd = &font_info_8x16; #endif if (loadfont) { /* XXX: We should set the colormap */ /* * set colors (B&W) */ vgaw(ba, VDAC_ADDRESS_W, 0); for (z = 0; z < 256; z++) { y = (z & 1) ? ((z > 7) ? 2 : 1) : 0; vgaw(ba, VDAC_DATA, etconscolors[y][0]); vgaw(ba, VDAC_DATA, etconscolors[y][1]); vgaw(ba, VDAC_DATA, etconscolors[y][2]); } /* * Enter a suitable mode to download the font. This * basically means sequential addressing mode */ s = splhigh(); WAttr(ba, 0x20 | ACT_ID_ATTR_MODE_CNTL, 0x0a); WSeq(ba, SEQ_ID_MAP_MASK, 0x04); WSeq(ba, SEQ_ID_MEMORY_MODE, 0x06); WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x02); WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x00); WGfx(ba, GCT_ID_MISC, 0x04); splx(s); /* * load text font into beginning of display memory. Each * character cell is 32 bytes long (enough for 4 planes) */ for (z = 0, c = fb; z < 256 * 32; z++) *c++ = 0; c = (unsigned char *) (fb) + (32 * fd->font_lo); f = fd->font_p; z = fd->font_lo; for (; z <= fd->font_hi; z++, c += (32 - fd->height)) for (y = 0; y < fd->height; y++) { *c++ = *f++; } } /* * Odd/Even addressing */ etregs->seq[SEQ_ID_MAP_MASK] = 0x03; etregs->seq[SEQ_ID_MEMORY_MODE] = 0x03; etregs->grf[GCT_ID_READ_MAP_SELECT] = 0x00; etregs->grf[GCT_ID_GRAPHICS_MODE] = 0x10; etregs->grf[GCT_ID_MISC] = 0x06; /* * Font height + underline location */ tmp = etregs->crt[CRT_ID_MAX_ROW_ADDRESS] & 0xe0; etregs->crt[CRT_ID_MAX_ROW_ADDRESS] = tmp | (fd->height - 1); tmp = etregs->crt[CRT_ID_UNDERLINE_LOC] & 0xe0; etregs->crt[CRT_ID_UNDERLINE_LOC] = tmp | (fd->height - 1); /* * Cursor setup */ etregs->crt[CRT_ID_CURSOR_START] = 0x00; etregs->crt[CRT_ID_CURSOR_END] = fd->height - 1; etregs->crt[CRT_ID_CURSOR_LOC_HIGH] = 0x00; etregs->crt[CRT_ID_CURSOR_LOC_LOW] = 0x00; /* * Enter text mode */ etregs->crt[CRT_ID_MODE_CONTROL] = 0xa3; etregs->attr[ACT_ID_ATTR_MODE_CNTL] = 0x0a; #if 1 if (loadfont || (etregs == &loc_regs)) #else if (etregs == &loc_regs) #endif et_hwrest(etregs); }