home *** CD-ROM | disk | FTP | other *** search
- /* Prefs.c */
-
- #include "Sys.h"
- #include "Curses.h"
-
- #include <ctype.h>
- #include <signal.h>
- #include <setjmp.h>
-
- #include "Util.h"
- #include "Cmds.h"
- #include "Progress.h"
- #include "Hostwin.h"
- #include "Prefs.h"
- #include "RCmd.h"
- #include "Bookmark.h"
- #include "Main.h"
-
- #ifdef USE_CURSES
-
- #include "WGets.h"
-
- /* This is the full-screen window that pops up when you run the
- * preferences editor.
- */
- WINDOW *gPrefsWin = NULL;
-
- extern void WAddCenteredStr(WINDOW *w, int y, char *str);
- void WAttr(WINDOW *w, int attr, int on);
-
- #endif /* USE_CURSES */
-
-
-
- jmp_buf gPrefsWinJmp;
- extern int gWinInit;
- extern string gAnonPassword;
- extern int gMayUTime, gStartupMsgs, gRemoteMsgs, gBlankLines;
- extern int gAnonOpen, gWhichProgMeter, gMaxLogSize, gMaxBookmarks;
- extern int gDefaultVisualMode, gTotalRuns, gRememberLCWD;
- extern int gNetworkTimeout, gTrace, gPreferredDataPortMode;
- extern longstring gLocalCWD, gPager, gDownloadDir;
- extern long gTotalXferKiloBytes, gTotalXferHSeconds;
- extern int gMarkTrailingSpace;
-
-
-
- PrefOpt gPrefOpts[] = {
- { "anonopen", "Default open mode:",
- kToggleMsg,
- PREFBOOL(gAnonOpen) },
- { "anonpass", "Anonymous password:",
- "Type new anonymous password, or hit <RETURN> to continue.",
- PREFSTR(gAnonPassword, kNotOkayIfEmpty, kGetAndEcho) },
- { "blank-lines", "Blank lines between cmds:",
- kToggleMsg,
- PREFBOOL(gBlankLines) },
- { "ftp-mode", "Default FTP mode:",
- kToggleMsg,
- PREFTOGGLE(gPreferredDataPortMode, kSendPortMode, kFallBackToSendPortMode) },
- { "logsize", "User log size:",
- "Enter the maximum number of bytes allowed for log file, or 0 for no log.",
- PREFINT(gMaxLogSize) },
- { "maxbookmarks", "Max bookmarks to save:",
- "Enter the max number of bookmarks for bookmarks file, or 0 for no limit.",
- PREFINT(gMaxBookmarks) },
- { "pager", "Pager:",
- "Type the pathname of the program you use to view text a page at a time.",
- PREFSTR(gPager, kOkayIfEmpty, kGetAndEcho) },
- { "progress-meter", "Progress meter:",
- kToggleMsg,
- PREFTOGGLE(gWhichProgMeter, kPrNone, kPrLast) },
- { "remote-msgs", "Remote messages:",
- kToggleMsg,
- PREFTOGGLE(gRemoteMsgs, kAllRmtMsgs, (kNoChdirMsgs | kNoConnectMsg)) },
- #if 0
- { "restore-lcwd", "Restore local CWD:",
- kToggleMsg,
- PREFBOOL(gRememberLCWD) },
- #endif
- { "startup-lcwd", "Startup in Local Dir:",
- "Type directory to always lcd to, or hit <RETURN> to not lcd at startup.",
- PREFSTR(gDownloadDir, kOkayIfEmpty, kGetAndEcho) },
- { "startup-msgs", "Startup messages:",
- kToggleMsg,
- PREFTOGGLE(gStartupMsgs, kNoStartupMsgs, (kStartupMsg | kTips)) },
- { "timeout", "Network timeout:",
- "Enter the maximum amount of time to wait on a connection before giving up.",
- PREFINT(gNetworkTimeout) },
- { "trace", "Trace logging:",
- kToggleMsg,
- PREFBOOL(gTrace) },
- { "utime", "File timestamps:",
- kToggleMsg,
- PREFBOOL(gMayUTime) },
- { "visual", "Screen graphics:",
- kToggleMsg,
- PREFBOOL(gDefaultVisualMode) },
- };
-
- /* These are options that are for information only, or options I don't feel
- * like wasting screen space on in the prefs editor.
- */
- PrefOpt gNonEditPrefOpts[] = {
- { "show-trailing-space", "Show trailing space:",
- kToggleMsg,
- PREFBOOL(gMarkTrailingSpace) },
- { "total-runs", NULL, NULL,
- PREFINT(gTotalRuns) },
- { "total-xfer-hundredths-of-seconds", NULL, NULL,
- PREFINT(gTotalXferHSeconds) },
- { "total-xfer-kbytes", NULL, NULL,
- PREFINT(gTotalXferKiloBytes) },
- };
-
- int gNumEditablePrefOpts = ((int)(sizeof(gPrefOpts) / sizeof(PrefOpt)));
- #define kNumNonEditablePrefOpts ((int)(sizeof(gNonEditPrefOpts) / sizeof(PrefOpt)))
-
-
-
-
-
- void TogglePref(int *val, int min, int max)
- {
- int newVal;
-
- newVal = *val + 1;
- if (newVal > max)
- newVal = min;
- *val = newVal;
- } /* TogglePref */
-
-
-
-
-
- void GetPrefSetting(char *dst, size_t siz, int item)
- {
- char *cp;
- string str;
- size_t len;
-
- *dst = '\0';
- switch (item) {
- case kAnonOpenPrefsWinItem:
- cp = gAnonOpen ? "anonymous" : "user & password";
- (void) Strncpy(dst, cp, siz);
- break;
-
- case kAnonPassPrefsWinItem:
- (void) Strncpy(dst, gAnonPassword, siz);
- break;
-
- case kBlankLinesWinItem:
- cp = gBlankLines ? "yes" : "no";
- (void) Strncpy(dst, cp, siz);
- break;
-
- case kFTPModePrefsWinItem:
- if (gPreferredDataPortMode == kFallBackToSendPortMode)
- cp = "Passive, but fall back to port if needed";
- else if (gPreferredDataPortMode == kPassiveMode)
- cp = "Passive FTP only (PASV)";
- else
- cp = "Send-Port FTP only (PORT)";
- (void) Strncpy(dst, cp, siz);
- break;
-
- case kLogSizePrefsWinItem:
- if (gMaxLogSize == 0)
- (void) Strncpy(str, "no logging", siz);
- else
- sprintf(str, "%d", gMaxLogSize);
- (void) Strncpy(dst, str, siz);
- break;
-
- case kMaxBookmarksWinItem:
- if (gMaxBookmarks == kNoBookmarkLimit)
- (void) Strncpy(str, "unlimited", siz);
- else
- sprintf(str, "%d", gMaxBookmarks);
- (void) Strncpy(dst, str, siz);
- break;
-
- case kPagerPrefsWinItem:
- if ((len = strlen(gPager)) > 47) {
- /* Abbreviate a long program path. */
- STRNCPY(str, "...");
- STRNCAT(str, gPager + len - 44);
- } else {
- if (gPager[0] == '\0')
- STRNCPY(str, "(none)");
- else
- STRNCPY(str, gPager);
- }
- (void) Strncpy(dst, str, siz);
- break;
-
- case kProgressPrefsWinItem:
- switch (gWhichProgMeter) {
- case kPrPercent: cp = "percent meter"; break;
- case kPrPhilBar: cp = "bar graph"; break;
- case kPrKBytes: cp = "kilobyte meter"; break;
- case kPrDots: cp = "hash dots"; break;
- case kPrStatBar: cp = "stat meter"; break;
- default: cp = "no progress reports";
- }
- (void) Strncpy(dst, cp, siz);
- break;
-
- case kRmtMsgsPrefsWinItem:
- if ((gRemoteMsgs & (kNoChdirMsgs | kNoConnectMsg)) == (kNoChdirMsgs | kNoConnectMsg))
- cp = "ignore startup messages and chdir messages";
- else if ((gRemoteMsgs & kNoChdirMsgs) != 0)
- cp = "ignore change-directory messages";
- else if ((gRemoteMsgs & kNoConnectMsg) != 0)
- cp = "ignore startup messages";
- else
- cp = "allow startup messages and chdir messages";
- (void) Strncpy(dst, cp, siz);
- break;
-
- case kStartupLCWDWinItem:
- cp = (gDownloadDir[0] != '\0') ? gDownloadDir :
- "(none)";
- (void) Strncpy(dst, cp, siz);
- break;
-
- case kStartupMsgsPrefsWinItem:
- if ((gStartupMsgs & (kStartupMsg | kTips)) == (kStartupMsg | kTips))
- cp = "headers and tips";
- else if ((gStartupMsgs & kStartupMsg) != 0)
- cp = "headers only";
- else if ((gStartupMsgs & kTips) != 0)
- cp = "tips only";
- else
- cp = "no startup messages";
- (void) Strncpy(dst, cp, siz);
- break;
-
- case kTimeoutPrefsWinItem:
- sprintf(dst, "%d", gNetworkTimeout);
- break;
-
- case kTracePrefsWinItem:
- if (gTrace) {
- cp = "yes";
- OpenTraceLog();
- } else {
- cp = "no";
- CloseTraceLog();
- }
- (void) Strncpy(dst, cp, siz);
- break;
-
- case kUTimePrefsWinItem:
- cp = gMayUTime ? "try to preserve file timestamps" :
- "do not preserve file timestamps";
- (void) Strncpy(dst, cp, siz);
- break;
-
- case kVisualPrefsWinItem:
- cp = gDefaultVisualMode == 1 ? "visual (curses)" : "line-oriented";
- (void) Strncpy(dst, cp, siz);
- break;
- }
- } /* GetPrefSetting */
-
-
-
- #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 UpdatePrefsWindow(int uptAll)
- {
- if (uptAll) {
- touchwin(gPrefsWin);
- }
- wnoutrefresh(gPrefsWin);
- doupdate();
- } /* UpdatePrefsWindow */
-
-
-
-
- /* This displays a message in the preferences window. */
- void PrefsWinWinMsg(char *msg)
- {
- int maxx, maxy;
-
- getmaxyx(gPrefsWin, maxy, maxx);
- mvwaddstr(gPrefsWin, maxy - 2, 0, msg);
- wclrtoeol(gPrefsWin);
- wmove(gPrefsWin, maxy - 1, 0);
- wrefresh(gPrefsWin);
- } /* PrefsWinWinMsg */
-
-
-
-
- /* Prompts for a line of input. */
- void PrefsWinGetStr(char *dst, int canBeEmpty, int canEcho)
- {
- string str;
- WGetsParams wgp;
- int maxx, maxy;
-
- getmaxyx(gPrefsWin, maxy, maxx);
- WAttr(gPrefsWin, kBold, 1);
- mvwaddstr(gPrefsWin, maxy - 1, 0, "> ");
- WAttr(gPrefsWin, kBold, 0);
- wclrtoeol(gPrefsWin);
- wrefresh(gPrefsWin);
- curs_set(1);
-
- wgp.w = gPrefsWin;
- wgp.sy = maxy - 1;
- wgp.sx = 2;
- wgp.fieldLen = maxx - 3;
- wgp.dst = str;
- wgp.dstSize = sizeof(str);
- 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", str);
-
- /* 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(gPrefsWin, maxy - 1, 0);
- wclrtoeol(gPrefsWin);
- wrefresh(gPrefsWin);
- curs_set(0);
- } /* PrefsWinGetStr */
-
-
-
-
-
- /* Prompts for an integer of input. */
- void PrefsWinGetNum(int *dst)
- {
- string str;
- WGetsParams wgp;
- int maxx, maxy;
-
- getmaxyx(gPrefsWin, maxy, maxx);
- WAttr(gPrefsWin, kBold, 1);
- mvwaddstr(gPrefsWin, maxy - 1, 0, "> ");
- WAttr(gPrefsWin, kBold, 0);
- wclrtoeol(gPrefsWin);
- wrefresh(gPrefsWin);
- curs_set(1);
-
- wgp.w = gPrefsWin;
- 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(gPrefsWin, maxy - 1, 0);
- wclrtoeol(gPrefsWin);
- wrefresh(gPrefsWin);
- curs_set(0);
- } /* PrefsWinGetNum */
-
-
-
-
- /* This is the meat of the preferences window. We can selectively update
- * portions of the window by using a bitmask with bits set for items
- * we want to update.
- */
- void PrefsWinDraw(int flags, int hilite)
- {
- int i;
- string value;
- char spec[32];
- int maxx, maxy;
-
- getmaxyx(gPrefsWin, maxy, maxx);
- /* Draw the keys the user can type in reverse text. */
- WAttr(gPrefsWin, kReverse, 1);
- for (i = kFirstPrefsWinItem; i <= kLastPrefsWinItem; i++) {
- if (TESTBIT(flags, i))
- mvwaddch(gPrefsWin, 2 + 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 = kQuitPrefsWinItem;
- if (TESTBIT(flags, i))
- mvwaddch(gPrefsWin, 3 + i, 2, 'X');
- WAttr(gPrefsWin, 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(gPrefsWin, kReverse, 1);
-
- sprintf(spec, " %%-28s%%-%ds",
- maxx - 28 - 6);
-
- for (i = kFirstPrefsWinItem; i <= kLastPrefsWinItem; i++) {
- if (TESTBIT(flags, i)) {
- GetPrefSetting(value, sizeof(value), i);
- mvwprintw(gPrefsWin, i + 2 , 3, spec, gPrefOpts[i].label, value);
- wclrtoeol(gPrefsWin);
- }
- }
-
- if (TESTBIT(flags, kQuitPrefsWinItem)) {
- mvwprintw(gPrefsWin, kQuitPrefsWinItem + 3, 3, " %-28s",
- "(Done editing)"
- );
- wclrtoeol(gPrefsWin);
- }
-
- if (hilite)
- WAttr(gPrefsWin, kReverse, 0);
-
- wmove(gPrefsWin, maxy - 1, 0);
- wrefresh(gPrefsWin);
- } /* PrefsWinDraw */
-
-
-
- /* The user can hit space to change values. For these toggle
- * functions we do an update each time so the user can see the change
- * immediately.
- */
- void PrefsWinToggle(int *val, int bitNum, int min, int max)
- {
- int c;
-
- while (1) {
- c = wgetch(gPrefsWin);
- TraceMsg("[%c, 0x%x]\n", c, c);
- if ((c == 'q') || (c == 10) || (c == 13)
- #ifdef KEY_ENTER
- || (c == KEY_ENTER)
- #endif
- )
- break;
- else if (isspace(c)) {
- TogglePref(val, min, max);
- PrefsWinDraw(BIT(bitNum), kHilite);
- }
- }
- } /* PrefsWinToggle */
-
-
-
-
- /*ARGSUSED*/
- void SigIntPrefsWin(void)
- {
- alarm(0);
- longjmp(gPrefsWinJmp, 1);
- } /* SigIntPrefsWin */
-
-
- #endif /* USE_CURSES */
-
-
-
-
-
- /* Runs the preferences editor. */
- int PrefsWindow(void)
- {
- #ifdef USE_CURSES
- int c, field, i;
-
- if (gWinInit) {
- gPrefsWin = newwin(LINES, COLS, 0, 0);
- if (gPrefsWin == NULL)
- return (kCmdErr);
-
- if (setjmp(gPrefsWinJmp) == 0) {
- /* Gracefully cleanup the screen if the user ^C's. */
- SIGNAL(SIGINT, SigIntPrefsWin);
-
- curs_set(0);
- cbreak();
- /* leaveok(gPrefsWin, TRUE); * Not sure if I like this... */
-
- /* Set the clear flag for the first update. */
- wclear(gPrefsWin);
-
- WAttr(gPrefsWin, kBold, 1);
- WAddCenteredStr(gPrefsWin, 0, "Preferences");
- WAttr(gPrefsWin, kBold, 0);
-
- PrefsWinDraw(kAllWindowItems, kNoHilite);
- while (1) {
- PrefsWinWinMsg("Select an item to edit by typing its corresponding letter.");
- c = wgetch(gPrefsWin);
- TraceMsg("[%c, 0x%x]\n", c, c);
- if (islower(c))
- c = toupper(c);
- if (!isupper(c))
- continue;
- if (c == 'X')
- break;
- field = c - 'A';
- i = field;
- if (i > kLastPrefsWinItem)
- continue;
-
- /* Hilite the current item to edit. */
- PrefsWinDraw(BIT(i), kHilite);
-
- /* Print the instructions. */
- PrefsWinWinMsg(gPrefOpts[i].msg);
-
- switch (gPrefOpts[i].type) {
- case kPrefInt:
- PrefsWinGetNum((int *) gPrefOpts[i].storage);
- break;
- case kPrefToggle:
- PrefsWinToggle((int *) gPrefOpts[i].storage,
- i, gPrefOpts[i].min, gPrefOpts[i].max);
- break;
- case kPrefStr:
- PrefsWinGetStr((char *) gPrefOpts[i].storage,
- gPrefOpts[i].min, /* Used for Empty */
- gPrefOpts[i].max /* Used for Echo */
- );
- break;
- }
-
- /* Update and unhilite it. */
- PrefsWinDraw(BIT(field), kNoHilite);
- }
- }
-
- delwin(gPrefsWin);
- gPrefsWin = NULL;
- UpdateScreen(1);
- flushinp();
- nocbreak();
- curs_set(1);
- }
- #endif /* USE_CURSES */
- return (kNoErr);
- } /* PrefsWindow */
-
-
-
-
-
- void ShowAll(void)
- {
- int i;
- string value;
-
- MultiLineInit();
- for (i = kFirstPrefsWinItem; i <= kLastPrefsWinItem; i++) {
- GetPrefSetting(value, sizeof(value), i);
- MultiLinePrintF("%-28s%s\n", gPrefOpts[i].label, value);
- }
- } /* ShowAll */
-
-
-
-
- static
- void ShowSetHelp(void)
- {
- int i;
-
- MultiLineInit();
- for (i = kFirstPrefsWinItem; i <= kLastPrefsWinItem; i++) {
- MultiLinePrintF("%-15s %s\n", gPrefOpts[i].name, gPrefOpts[i].label);
- }
- } /* ShowSetHelp */
-
-
-
-
-
- int SetCmd(int argc, char **argv)
- {
- int i, j, match;
- size_t len;
- string value;
-
- if ((argc == 1) || ISTREQ(argv[1], "all")) {
- ShowAll();
- } else if (ISTREQ(argv[1], "help")) {
- ShowSetHelp();
- } else {
- len = strlen(argv[1]);
- for (i = kFirstPrefsWinItem, match = -1; i <= kLastPrefsWinItem; i++) {
- if (ISTRNEQ(gPrefOpts[i].name, argv[1], len)) {
- if (match >= 0) {
- Error(kDontPerror, "Ambiguous option name \"%s.\"\n",
- argv[1]);
- return (kCmdErr);
- }
- match = i;
- }
- }
- if (match < 0) {
- Error(kDontPerror, "Unknown option name \"%s.\"\n",
- argv[1]);
- return (kCmdErr);
- }
- i = match;
- switch (gPrefOpts[i].type) {
- case kPrefInt:
- if (argc > 2)
- AtoIMaybe((int *) gPrefOpts[i].storage, argv[2]);
- break;
- case kPrefToggle:
- if (argc > 2) {
- /* User can set it directly instead of cycling through
- * the choices.
- */
- AtoIMaybe((int *) &j, argv[2]);
- if (j < gPrefOpts[i].min)
- j = gPrefOpts[i].min;
- else if (j > gPrefOpts[i].max)
- j = gPrefOpts[i].max;
- * (int *) gPrefOpts[i].storage = j;
- } else {
- /* User toggled to the next choice. */
- TogglePref((int *) gPrefOpts[i].storage,
- gPrefOpts[i].min, gPrefOpts[i].max);
- }
- break;
- case kPrefStr:
- if (argc > 2)
- (void) Strncpy((char *) gPrefOpts[i].storage,
- argv[2], gPrefOpts[i].siz);
- break;
- }
-
- /* Print the (possibly new) value. */
- GetPrefSetting(value, sizeof(value), i);
- PrintF("%-28s%s\n", gPrefOpts[i].label, value);
- }
- return (kNoErr);
- } /* SetCmd */
-
-
-
-
-
- int PrefsCmd(void)
- {
- #ifdef USE_CURSES
- int err;
-
- if (!gWinInit) {
- EPrintF("%s\n%s\n",
- "The preferences editor only works in visual mode.",
- "However, you can use the 'set' command to set a single option at a time."
- );
- return (kCmdErr);
- }
- err = PrefsWindow();
- Beep(0); /* User should be aware that it took a while, so no beep. */
- return (err);
- #else
- EPrintF("%s\n%s\n",
- "You can't do this because the program doesn't have the curses library.",
- "However, you can use the 'set' command to set a single option at a time."
- );
- return (kCmdErr);
- #endif /* USE_CURSES */
- } /* PrefsCmd */
-
-
-
-
- void WritePrefs(void)
- {
- longstring path;
- FILE *fp;
- int i;
-
- if (gOurDirectoryPath[0] == '\0')
- return; /* Don't create in root directory. */
-
- OurDirectoryPath(path, sizeof(path), kPrefsName);
- fp = fopen(path, "w");
- if (fp == NULL) {
- Error(kDoPerror, "Can't open %s for writing.\n", path);
- return;
- }
- for (i = kFirstPrefsWinItem; i <= kLastPrefsWinItem; i++) {
- switch (gPrefOpts[i].type) {
- case kPrefInt:
- case kPrefToggle:
- fprintf(fp, "%s %d\n", gPrefOpts[i].name,
- * (int *) gPrefOpts[i].storage);
- break;
- case kPrefStr:
- fprintf(fp, "%s %s\n", gPrefOpts[i].name,
- (char *) gPrefOpts[i].storage);
- break;
- }
- }
- for (i = 0; i < kNumNonEditablePrefOpts; i++) {
- switch (gNonEditPrefOpts[i].type) {
- case kPrefInt:
- case kPrefToggle:
- fprintf(fp, "%s %d\n", gNonEditPrefOpts[i].name,
- * (int *) gNonEditPrefOpts[i].storage);
- break;
- case kPrefStr:
- fprintf(fp, "%s %s\n", gNonEditPrefOpts[i].name,
- (char *) gNonEditPrefOpts[i].storage);
- break;
- }
- }
-
- fclose(fp);
- } /* WritePrefs */
-
-
-
-
-
- static
- int PrefSearchProc(char *key, const PrefOpt *b)
- {
- return (ISTRCMP(key, (*b).name));
- } /* PrefSearchProc */
-
-
-
-
-
- void ReadPrefs(void)
- {
- longstring path;
- FILE *fp;
- string option;
- longstring val;
- longstring line;
- int o;
- PrefOpt *pop;
-
- OurDirectoryPath(path, sizeof(path), kPrefsName);
- fp = fopen(path, "r");
- if (fp == NULL) {
- /* It's okay if we don't have one. */
- return;
- }
-
- while (FGets(line, (int) sizeof(line) - 1, fp) != NULL) {
- if (sscanf(line, "%s", option) < 1)
- continue;
- o = strlen(option) + 1;
- STRNCPY(val, line + o);
- pop = (PrefOpt *) BSEARCH(option, gPrefOpts, SZ(gNumEditablePrefOpts),
- sizeof(PrefOpt), PrefSearchProc);
- if (pop == NULL) {
- pop = (PrefOpt *) BSEARCH(option, gNonEditPrefOpts,
- SZ(kNumNonEditablePrefOpts),
- sizeof(PrefOpt), PrefSearchProc);
- if (pop == NULL) {
- Error(kDontPerror, "Unrecognized preference option \"%s\".\n",
- option);
- continue;
- }
- }
- switch (pop->type) {
- case kPrefInt:
- case kPrefToggle:
- * (int *) pop->storage = atoi(val);
- break;
- case kPrefStr:
- (void) Strncpy((char *) pop->storage, val, pop->siz);
- break;
- }
- }
-
- fclose(fp);
- } /* ReadPrefs */
-