home *** CD-ROM | disk | FTP | other *** search
- /* Hostwin.c */
-
- #include "Sys.h"
- #include "Curses.h"
-
- #include <ctype.h>
- #include <signal.h>
- #include <setjmp.h>
-
- #include "Util.h"
- #include "Cmds.h"
- #include "Bookmark.h"
- #include "Open.h"
- #include "Hostwin.h"
-
- #ifdef USE_CURSES
-
- #include "WGets.h"
-
- /* This is the full-screen window that pops up when you run the
- * host editor. Not much is done with it, except display directions
- * and getting host editor commands.
- */
- WINDOW *gHostWin = NULL;
-
- /* This is a window devoted solely to serve as a scrolling list
- * of bookmarks.
- */
- WINDOW *gHostListWin = NULL;
-
- /* This is another full-screen window that opens when a user wants
- * to edit the parameters for a site.
- */
- WINDOW *gEditHostWin = NULL;
-
- extern void WAddCenteredStr(WINDOW *w, int y, char *str);
- void WAttr(WINDOW *w, int attr, int on);
-
- #endif /* USE_CURSES */
-
- /* This is an index into the host list. This indicates the position
- * in the host list where we draw the current "page" of the host list.
- */
- int gHostListWinStart;
-
- /* This index is the currently selected host. This index must be >=
- * to gHostListWinStart and less than gHostListWinStart + pageLen - 1,
- * so that this host will show up in the current page of the host list.
- */
- int gHilitedHost;
-
- /* This is a pointer to the actual information of the currently
- * selected host.
- */
- BookmarkPtr gCurHostListItem;
-
- /* How many lines compose a "page" in the host list's scrolling window. */
- int gHostListPageSize;
-
- /* A flag saying if we need to erase a message after the next input key. */
- int gNeedToClearMsg = 0;
-
- /* When we edit gCurHostListItem's stuff, we actually edit a copy of it.
- * This is so we could restore the information if the user wanted to
- * abort the changes.
- */
- Bookmark gEditRsi;
-
- jmp_buf gHostWinJmp;
-
- extern int gWinInit, gNumBookmarks, gRmtInfoIsNew;
- extern BookmarkPtrList gBookmarks;
- extern BookmarkPtr gHosts;
- extern Bookmark gRmtInfo;
- extern string gEmailAddress, gAnonPassword;
- extern unsigned int gFTPPort;
-
- void AtoIMaybe(int *dst, char *str)
- {
- char *cp;
-
- /* Don't change the value if the user just hit return. */
- for (cp = str; *cp != '\0'; cp++)
- if (isdigit(*cp))
- break;
- if (isdigit(*cp))
- *dst = atoi(str);
- } /* AtoIMaybe */
-
-
-
-
- #ifdef USE_CURSES
-
- /* Draws the screen when we're using the host editor's main screen.
- * You can can specify whether to draw each character whether it needs
- * it or not if you like.
- */
- void UpdateHostWindows(int uptAll)
- {
- if (uptAll) {
- DrawHostList();
- touchwin(gHostListWin);
- touchwin(gHostWin);
- }
- wnoutrefresh(gHostListWin);
- wnoutrefresh(gHostWin);
- doupdate();
- } /* UpdateHostWindows */
-
-
-
- /* This draws the scrolling list of bookmarks, and hilites the currently
- * selected host.
- */
- void DrawHostList(void)
- {
- int lastLine, i;
- BookmarkPtr rsip;
- string str;
- 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,
- "%s",
- "Number of bookmarks"
- );
- WAttr(gHostWin, kUnderline, 0);
- wprintw(
- gHostWin,
- ": %3d",
- gNumBookmarks
- );
- sprintf(spec, "%%-16s %%-%ds", lmaxx - 17);
- lastLine = lmaxy + gHostListWinStart;
- for (i=gHostListWinStart; (i<lastLine) && (i<gNumBookmarks); i++) {
- rsip = gBookmarks[i];
- if (rsip == gCurHostListItem)
- WAttr(gHostListWin, kReverse, 1);
- sprintf(str, spec, rsip->bookmarkName, rsip->name);
- str[lmaxx] = '\0';
- mvwaddstr(gHostListWin, i - gHostListWinStart, 0, str);
- if (rsip == gCurHostListItem)
- WAttr(gHostListWin, kReverse, 0);
- }
-
- /* Add 'vi' style empty-lines. */
- for ( ; i<lastLine; ++i) {
- mvwaddstr(gHostListWin, i - gHostListWinStart, 0, "~");
- wclrtoeol(gHostListWin);
- }
- wmove(gHostWin, maxy - 3, 2);
- sprintf(spec, "%%-%ds", maxx - 4);
- if ((gCurHostListItem == NULL) || (gCurHostListItem->comment[0] == '\0'))
- str[0] = '\0';
- else {
- STRNCPY(str, "``");
- STRNCAT(str, gCurHostListItem->comment);
- AbbrevStr(str + 2, gCurHostListItem->comment, maxx - 8, 1);
- STRNCAT(str, "''");
- }
- wprintw(gHostWin, spec, str);
- wmove(gHostWin, maxy - 1, 0);
- UpdateHostWindows(0);
- } /* DrawHostList */
-
-
-
-
- /* This prompts for a key of input when in the main host editor window. */
- int HostWinGetKey(void)
- {
- int c;
- int maxy, maxx;
-
- getmaxyx(gHostWin, maxy, maxx);
- wmove(gHostWin, maxy - 1, 0);
- c = wgetch(gHostWin);
- TraceMsg("[%c, 0x%x]\n", c, c);
- return (c);
- } /* HostWinGetKey */
-
-
-
- static
- void NewHilitedHostIndex(int newIdx)
- {
- int oldIdx, lastLine;
-
- if (gNumBookmarks <= 0) {
- HostWinMsg(
- "No bookmarks in the list. Try a /new, or open a site manually to add one.");
- } else {
- oldIdx = gHilitedHost;
- if (gNumBookmarks < gHostListPageSize)
- lastLine = gHostListWinStart + gNumBookmarks - 1;
- else
- lastLine = gHostListWinStart + gHostListPageSize - 1;
- if (newIdx < gHostListWinStart) {
- /* Will need to scroll the window up. */
- if (newIdx < 0) {
- newIdx = 0;
- if (oldIdx == newIdx)
- HostWinMsg("You are at the top of the list.");
- }
- gHilitedHost = gHostListWinStart = newIdx;
- } else if (newIdx > lastLine) {
- /* Will need to scroll the window down. */
- if (newIdx > (gNumBookmarks - 1)) {
- newIdx = gNumBookmarks - 1;
- if (oldIdx == newIdx)
- HostWinMsg("You are at the bottom of the list.");
- }
- gHilitedHost = newIdx;
- gHostListWinStart = newIdx - (gHostListPageSize - 1);
- if (gHostListWinStart < 0)
- gHostListWinStart = 0;
- } else {
- /* Don't need to scroll window, just move pointer. */
- gHilitedHost = newIdx;
- }
- gCurHostListItem = gBookmarks[gHilitedHost];
- if (oldIdx != newIdx)
- DrawHostList();
- }
- } /* NewHilitedHostIndex */
-
-
-
-
- /* You can zip to a different area of the list without using the arrow
- * or page scrolling keys. Just type a letter, and the list will scroll
- * to the first host starting with that letter.
- */
- void HostWinZoomTo(int c)
- {
- int i, j;
-
- if (gNumBookmarks > 0) {
- if (islower(c))
- c = toupper(c);
- for (i=0; i<gNumBookmarks - 1; i++) {
- j = gBookmarks[i]->bookmarkName[0];
- if (islower(j))
- j = toupper(j);
- if (j >= c)
- break;
- }
- NewHilitedHostIndex(i);
- } else {
- HostWinMsg("No bookmarks to select. Try a /new.");
- }
- DrawHostList();
- } /* HostWinZoomTo */
-
-
-
-
-
- void HostListLineUp(void)
- {
- NewHilitedHostIndex(gHilitedHost - 1);
- } /* HostListLineUp */
-
-
-
-
-
- void HostListLineDown(void)
- {
- NewHilitedHostIndex(gHilitedHost + 1);
- } /* HostListLineDown */
-
-
-
-
- void HostListPageUp(void)
- {
- NewHilitedHostIndex(gHilitedHost - gHostListPageSize);
- } /* HostListPageUp */
-
-
-
-
- void HostListPageDown(void)
- {
- NewHilitedHostIndex(gHilitedHost + gHostListPageSize);
- } /* HostListPageDown */
-
-
-
- /* This marks the start of a section that belongs to the Bookmark Options
- * window. This window pops up on top of the host editor's main window
- * when you wish to edit a site's settings. When the user finishes,
- * we close it and the host editor resumes.
- */
-
- /* This displays a message in the Bookmark Options window. */
- void EditHostWinMsg(char *msg)
- {
- int maxy, maxx;
-
- getmaxyx(gEditHostWin, maxy, maxx);
- mvwaddstr(gEditHostWin, maxy - 2, 0, msg);
- wclrtoeol(gEditHostWin);
- wmove(gEditHostWin, maxy - 1, 0);
- wrefresh(gEditHostWin);
- } /* EditHostWinMsg */
-
-
-
-
- /* Prompts for a line of input. */
- void EditHostWinGetStr(char *dst, size_t size, int canBeEmpty, int canEcho)
- {
- string str;
- WGetsParams wgp;
- int maxy, maxx;
-
- WAttr(gEditHostWin, kBold, 1);
- getmaxyx(gEditHostWin, maxy, maxx);
- mvwaddstr(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. */
-
- TraceMsg("[%s]\n", wgp.dst);
-
- /* 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 */
-
-
-
-
-
- /* Prompts for an integer of input. */
- void EditHostWinGetNum(int *dst)
- {
- WGetsParams wgp;
- string str;
- int maxy, maxx;
-
- getmaxyx(gEditHostWin, maxy, maxx);
- WAttr(gEditHostWin, kBold, 1);
- mvwaddstr(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. */
-
- TraceMsg("[%s]\n", str);
- AtoIMaybe(dst, str);
- wmove(gEditHostWin, maxy - 1, 0);
- wclrtoeol(gEditHostWin);
- wrefresh(gEditHostWin);
- curs_set(0);
- } /* EditHostWinGetNum */
-
-
-
-
- /* 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;
- string str;
- char spec[32];
- 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:",
- gEditRsi.user[0] == '\0' ? "anonymous" : gEditRsi.user
- );
- wclrtoeol(gEditHostWin);
- }
- if (TESTBIT(flags, kPassEditWindowItem)) {
- if (gEditRsi.pass[0] == '\0' && gEditRsi.user[0] == '\0')
- STRNCPY(str, gAnonPassword);
- mvwprintw(gEditHostWin, kPassEditWindowItem + f, 3, spec,
- "Password:",
- strcmp(str, gAnonPassword) ? "********" : 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, maxx - 32, 0);
- mvwprintw(gEditHostWin, kDirEditWindowItem + f, 3, spec,
- "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);
- mvwprintw(gEditHostWin, kPortEditWindowItem + f, 3, spec,
- "Port:",
- str
- );
- wclrtoeol(gEditHostWin);
- }
- 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);
- }
- if (TESTBIT(flags, kCommentEditWindowItem)) {
- if (gEditRsi.comment[0] == '\0')
- STRNCPY(str, "(none)");
- else
- AbbrevStr(str, gEditRsi.comment, 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 */
-
-
-
- /* The user can hit space to change the transfer type. For these toggle
- * functions we do an update each time so the user can see the change
- * immediately.
- */
- void ToggleXferType(void)
- {
- int c;
-
- while (1) {
- c = wgetch(gEditHostWin);
- TraceMsg("[%c, 0x%x]\n", c, c);
- if ((c == 'x') || (c == 10) || (c == 13)
- #ifdef KEY_ENTER
- || (c == KEY_ENTER)
- #endif
- )
- break;
- else if (isspace(c)) {
- if (gEditRsi.xferType == 'A')
- gEditRsi.xferType = 'I';
- else if ((gEditRsi.xferType == 'B') || (gEditRsi.xferType == 'I'))
- gEditRsi.xferType = 'T';
- else
- gEditRsi.xferType = 'A';
- EditHostWinDraw(BIT(kXferTypeEditWindowItem), kHilite);
- }
- }
- } /* ToggleXferType */
-
-
-
-
- void EditWinToggle(int *val, int bitNum, int min, int max)
- {
- int c;
-
- while (1) {
- c = wgetch(gEditHostWin);
- TraceMsg("[%c, 0x%x]\n", c, c);
- if ((c == 'x') || (c == 10) || (c == 13)
- #ifdef KEY_ENTER
- || (c == KEY_ENTER)
- #endif
- )
- break;
- else if (isspace(c)) {
- *val = *val + 1;
- if (*val > max)
- *val = min;
- EditHostWinDraw(BIT(bitNum), kHilite);
- }
- }
- } /* EditWinToggle */
-
-
-
- /* This opens and handles the site options window. */
- void HostWinEdit(void)
- {
- long amt;
- double rate;
- char rstr[32];
- int c, field;
- int needUpdate;
- string str;
-
- if (gCurHostListItem != NULL) {
- gEditHostWin = newwin(LINES, COLS, 0, 0);
- if (gEditHostWin == NULL)
- return;
-
-
- /* 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;
-
- if (gEditRsi.lastCall != (time_t) 0) {
- strcpy(str, ctime(&gEditRsi.lastCall));
- /* Why-o-why does ctime append a newline. I hate that! */
- str[strlen(str) - 1] = '\0';
- mvwprintw(gEditHostWin, 2, 5,
- "Number of calls: %d. Last call: %s",
- gEditRsi.nCalls,
- str
- );
- amt = gEditRsi.xferKbytes;
- if (amt > 0) {
- if (amt < 1000) {
- sprintf(str, "%ld kBytes", amt);
- } else if (amt < 1000000) {
- sprintf(str, "%.2f MBytes", ((double) amt / 1000.0));
- } else {
- sprintf(str, "%.2f GBytes", ((double) amt / 1000000.0));
- }
-
- rate = (double) amt / gEditRsi.xferHSeconds * 100.0;
- if (rate > 0) {
- if (rate < 1000.0) {
- sprintf(rstr, "%.2f kBytes/sec", rate);
- } else if (rate < 1000000.0) {
- sprintf(rstr, "%.2f MBytes/sec", rate / 1000.0);
- } else {
- sprintf(rstr, "%.2f GBytes/sec", rate / 1000000.0);
- }
- mvwprintw(gEditHostWin, 3, 5,
- "You have transferred %s, averaging %s.",
- str,
- rstr
- );
- }
- }
- }
-
- EditHostWinDraw(kAllWindowItems, kNoHilite);
- field = 1;
- while (1) {
- EditHostWinMsg("Select an item to edit by typing its corresponding letter.");
- c = wgetch(gEditHostWin);
- TraceMsg("[%c, 0x%x]\n", c, c);
- 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);
- 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 directory path to start in after a connection is established.");
- EditHostWinGetStr(gEditRsi.dir, sizeof(gEditRsi.dir), 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;
-
- 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;
-
- 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;
- SortBookmarks();
- NewHilitedHostIndex(gCurHostListItem->index);
- UpdateHostWindows(1);
- }
- } /* HostWinEdit */
-
-
-
- /* Clones an existing site in the host list. */
- void HostWinDup(void)
- {
- if (gCurHostListItem != NULL) {
- gCurHostListItem = DuplicateBookmark(gCurHostListItem);
- gHilitedHost = gCurHostListItem->index;
- } else
- HostWinMsg("Nothing to duplicate.");
- DrawHostList();
- } /* HostWinDup */
-
-
-
-
- /* Removes a site from the host list. */
- void HostWinDelete(void)
- {
- BookmarkPtr toDelete;
- int newi;
-
- if (gCurHostListItem != NULL) {
- toDelete = gCurHostListItem;
-
- /* Need to choose a new active host after deletion. */
- if (gHilitedHost == gNumBookmarks - 1) {
- if (gNumBookmarks == 1) {
- newi = -1; /* None left. */
- } else {
- /* At last one before delete. */
- newi = gHilitedHost - 1;
- }
- } else {
- /* Won't need to increment gHilitedHost here, since after deletion,
- * the next one will move up into this slot.
- */
- newi = gHilitedHost;
- }
- DeleteBookmark(toDelete);
- if (newi < 0)
- gCurHostListItem = NULL;
- else {
- gCurHostListItem = gBookmarks[newi];
- gHilitedHost = newi;
- }
- } else
- HostWinMsg("Nothing to delete.");
- DrawHostList();
- } /* HostWinDelete */
-
-
-
-
- /* Adds a new site to the host list, with default settings in place. */
- void HostWinNew(void)
- {
- BookmarkPtr rsip;
- Bookmark rsi;
-
- SetNewBookmarkDefaults(&rsi);
- rsip = AddBookmarkPtr(&rsi);
- rsip->port = gFTPPort;
- SortBookmarks();
- gCurHostListItem = rsip;
- gHilitedHost = rsip->index;
- gHostListWinStart = rsip->index - gHostListPageSize + 1;
- if (gHostListWinStart < 0)
- gHostListWinStart = 0;
- DrawHostList();
- } /* HostWinNew */
-
-
-
-
- /* This displays a message in the host editor's main window.
- * Used mostly for error messages.
- */
- void HostWinMsg(char *msg)
- {
- int maxy, maxx;
-
- getmaxyx(gHostWin, maxy, maxx);
- mvwaddstr(gHostWin, maxy - 2, 0, msg);
- wclrtoeol(gHostWin);
- wmove(gHostWin, maxy - 1, 0);
- wrefresh(gHostWin);
- beep();
- gNeedToClearMsg = 1;
- } /* HostWinMsg */
-
-
-
-
- /* Prompts for a line of input. */
- void HostWinGetStr(char *str, size_t size)
- {
- WGetsParams wgp;
- int maxy, maxx;
-
- getmaxyx(gHostWin, maxy, maxx);
- mvwaddstr(gHostWin, maxy - 1, 0, "/");
- wclrtoeol(gHostWin);
- wrefresh(gHostWin);
- curs_set(1);
- wgp.w = gHostWin;
- wgp.sy = maxy - 1;
- wgp.sx = 1;
- wgp.fieldLen = maxx - 1;
- wgp.dst = str;
- wgp.dstSize = size;
- wgp.useCurrentContents = 0;
- wgp.echoMode = wg_RegularEcho;
- wgp.history = wg_NoHistory;
- (void) wg_Gets(&wgp);
- cbreak(); /* wg_Gets turns off cbreak and delay. */
-
- TraceMsg("[%s]\n", str);
- wmove(gHostWin, maxy - 1, 0);
- wclrtoeol(gHostWin);
- wrefresh(gHostWin);
- curs_set(0);
- } /* HostWinGetStr */
-
-
-
-
- /*ARGSUSED*/
- void SigIntHostWin(/* int sigNum */ void)
- {
- alarm(0);
- longjmp(gHostWinJmp, 1);
- } /* SigIntHostWin */
-
-
- #endif /* USE_CURSES */
-
-
- /* Runs the host editor. Another big use for this is to open sites
- * that are in your host list.
- */
- int HostWindow(void)
- {
- #ifdef USE_CURSES
- int c;
- string cmd;
- volatile BookmarkPtr toOpen;
- VSig_t si;
- int maxy, maxx;
- int lmaxy, lmaxx;
- OpenOptions openopt;
-
- si = kNoSignalHandler;
- if (gWinInit) {
- gHostListWin = NULL;
- gHostWin = NULL;
-
- gHostWin = newwin(LINES, COLS, 0, 0);
- if (gHostWin == NULL)
- return (kCmdErr);
-
- 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
-
- if (setjmp(gHostWinJmp) == 0) {
- /* Gracefully cleanup the screen if the user ^C's. */
- si = (VSig_t) SIGNAL(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 = gBookmarks[gHilitedHost];
-
- /* Initially, we don't want to connect to any site in
- * the host list.
- */
- toOpen = NULL;
-
- WAttr(gHostWin, kBold, 1);
- WAddCenteredStr(gHostWin, 0, "Bookmark Editor");
- WAttr(gHostWin, kBold, 0);
-
- mvwaddstr(gHostWin, 3, 2, "Open selected site: <enter>");
- mvwaddstr(gHostWin, 4, 2, "Edit selected site: /ed");
- mvwaddstr(gHostWin, 5, 2, "Delete selected site: /del");
- mvwaddstr(gHostWin, 6, 2, "Duplicate selected site: /dup");
- mvwaddstr(gHostWin, 7, 2, "Add a new site: /new");
- mvwaddstr(gHostWin, 9, 2, "Up one: <u>");
- mvwaddstr(gHostWin, 10, 2, "Down one: <d>");
- mvwaddstr(gHostWin, 11, 2, "Previous page: <p>");
- mvwaddstr(gHostWin, 12, 2, "Next page: <n>");
- mvwaddstr(gHostWin, 14, 2, "Capital letters selects first");
- mvwaddstr(gHostWin, 15, 2, " site starting with the letter.");
- mvwaddstr(gHostWin, 17, 2, "Exit the bookmark editor: <x>");
-
- /* Initialize the scrolling host list window. */
- gHostListWin = subwin(
- gHostWin,
- LINES - 7,
- 40,
- 3,
- COLS - 40 - 2
- );
- if (gHostListWin == NULL)
- return (kCmdErr);
- getmaxyx(gHostListWin, lmaxy, lmaxx);
- getmaxyx(gHostWin, maxy, maxx);
- gHostListPageSize = lmaxy;
- DrawHostList();
- wmove(gHostWin, maxy - 1, 0);
- UpdateHostWindows(1);
-
- while (1) {
- 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 */
- case 13: /* ^M == carriage return */
- #ifdef KEY_ENTER
- case KEY_ENTER:
- #endif
- if (gCurHostListItem == NULL)
- HostWinMsg("Nothing to open. Try 'open sitename' from the main screen.");
- else {
- toOpen = (volatile BookmarkPtr) gCurHostListItem;
- goto done;
- }
- break;
-
- case kControl_L:
- UpdateHostWindows(1);
- break;
-
- case 'u':
- case 'k': /* vi up key */
- #ifdef KEY_UP
- case KEY_UP:
- #endif
- HostListLineUp();
- break;
-
- case 'd':
- case 'j': /* vi down key */
- #ifdef KEY_DOWN
- case KEY_DOWN:
- #endif
- HostListLineDown();
- break;
-
- case 'p':
- #ifdef KEY_LEFT
- case KEY_LEFT:
- #endif
- #ifdef KEY_PPAGE
- case KEY_PPAGE:
- #endif
- HostListPageUp();
- break;
-
- case 'n':
- #ifdef KEY_RIGHT
- case KEY_RIGHT:
- #endif
- #ifdef KEY_NPAGE
- case KEY_NPAGE:
- #endif
- HostListPageDown();
- break;
-
- #ifdef KEY_END
- case KEY_END:
- #endif
- case 'x':
- case 'q':
- goto done;
-
- default:
- HostWinMsg("Invalid key.");
- break;
- }
- }
- }
- SIGNAL(SIGINT, SIG_IGN);
- done:
- if (gHostListWin != NULL)
- delwin(gHostListWin);
- if (gHostWin != NULL)
- delwin(gHostWin);
- gHostListWin = gHostWin = NULL;
- curs_set(1);
- nocbreak();
- UpdateScreen(1);
- flushinp();
- if (si != (Sig_t) kNoSignalHandler)
- SIGNAL(SIGINT, si);
- if (toOpen != (volatile BookmarkPtr) 0) {
- /* If the user selected a site to open, connect to it now. */
- InitOpenOptions(&openopt);
- STRNCPY(openopt.hostname, ((BookmarkPtr) toOpen)->bookmarkName);
- GetBookmark(openopt.hostname, sizeof(openopt.hostname));
- openopt.port = gRmtInfo.port;
- Beep(0); /* Reset beep timer. */
- return (Open(&openopt));
- }
- }
- #endif /* USE_CURSES */
- Beep(0); /* User should be aware that it took a while, so no beep. */
- return (kNoErr);
- } /* HostWindow */
-
-
-
-
- int HostsCmd(void)
- {
- #ifdef USE_CURSES
- if (!gWinInit) {
- Error(kDontPerror, "This only works in visual mode.\n");
- return (kCmdErr);
- }
- return HostWindow();
- #else
- Error(kDontPerror,
- "You can't do this because the program doesn't have the curses library.\n");
- return (kCmdErr);
- #endif /* USE_CURSES */
- } /* HostsCmd */
-