/********** * Copyright (c) 2004 Greg Parker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **********/ #include "includes.h" #include "prefs.h" // There is one global default prefs list. // There is also a set of override values for each connection, mostly // for terminal settings. // Each preference is a RESOURCE // res type: 'dflt' or some ID for a connection override // res id: which pref /* interface: echo password (NO) keyboard pane(s) terminal: TERM type ("xterm") scrollback line count (500?) scroll down on input (NO) scroll down on keypress (YES) ssh: compression (NO) (fixme implement) ciphers ("aes128-cbc,3des-cbc") authmethod (fixme implement) putty terminal: wrap_mode (YES==autowrap) dec_om "DEC Origin Mode" (YES) lfhascr "Implicit CR in every LF" (NO) bce "Background Color Erase" (?) blink_text "Blink" (NO) answerback "Answerback to ^E" ("pssh") localecho (NO) localedit (NO) printing (NO) putty keyboard: bksp_is_delete "Backspace is DEL" (YES==^? rather than ^H) rxvt_homeend "rxvt Home and End" (NO) funky_type "Function Keys" (DIGITAL, Linux, xterm, VT400, VT100+, SCO) app_cursor "Application Cursor Keys" (NO?) app_keypad "Application Keypad" (NO?) nethack "NetHack Keypad" (NO) compose (NO) (use real compose key on keyboard?) ctrlalt (NO) lots more putty... */ #define noRecord ((UInt16)0xffff) static DmOpenRef PrefsDB = 0; // fixme implement overrides extern DmOpenRef OpenDB(UInt32 type, char *name, Boolean resDB, Boolean create); int PrefsInit(void) { PrefsDB = OpenDB('Pref', "pssh Preferences", true, true); return (PrefsDB != 0); } static MemHandle PrefsGetHandle(uint32_t which, Boolean fallback) { UInt16 index; // fixme search override here unless fallback==false // search default prefs index = DmFindResource(PrefsDB, 'dflt', which, NULL); if (index == noRecord) return NULL; return DmGetResourceIndex(PrefsDB, index); } uint32_t PrefsGetInt(uint32_t which, uint32_t defaultValue) { uint32_t result; uint32_t *p; MemHandle h = PrefsGetHandle(which, true); if (!h) return defaultValue; if (MemHandleSize(h) != 4) return defaultValue; p = MemHandleLock(h); result = *p; MemHandleUnlock(h); DmReleaseResource(h); return result; } void PrefsPutInt(uint32_t which, uint32_t value) { uint32_t *p; MemHandle h = PrefsGetHandle(which, false); if (h && MemHandleSize(h) == sizeof(value)) { // resource exists, and it's the right size p = MemHandleLock(h); DmWrite(p, 0, &value, sizeof(value)); MemHandleUnlock(h); DmReleaseResource(h); return; } else if (h) { // resource exists, but its the wrong size h = DmResizeResource(h, sizeof(value)); p = MemHandleLock(h); DmWrite(p, 0, &value, sizeof(value)); MemHandleUnlock(h); DmReleaseResource(h); } else { // resource does not exist h = DmNewResource(PrefsDB, 'dflt', which, sizeof(value)); p = MemHandleLock(h); DmWrite(p, 0, &value, sizeof(value)); MemHandleUnlock(h); DmReleaseResource(h); } } char *PrefsGetString(uint32_t which, char *defaultValue) { char *result; char *p; size_t size; MemHandle h = PrefsGetHandle(which, true); if (!h) return arena_strdup(defaultValue); size = MemHandleSize(h); p = MemHandleLock(h); result = arena_malloc(size + 1); // be paranoid about nul terminator memcpy(result, p, size); result[size] = '\0'; MemHandleUnlock(h); DmReleaseResource(h); return result; } void PrefsPutString(uint32_t which, char *value) { char *p; size_t sizeNeeded = strlen(value)+1; MemHandle h = PrefsGetHandle(which, false); if (h && MemHandleSize(h) >= sizeNeeded) { // resource exists, and it's big enough p = MemHandleLock(h); DmWrite(p, 0, value, sizeNeeded); MemHandleUnlock(h); DmReleaseResource(h); return; } else if (h) { // resource exists, but it's the wrong size h = DmResizeResource(h, sizeNeeded); p = MemHandleLock(h); DmWrite(p, 0, value, sizeNeeded); MemHandleUnlock(h); DmReleaseResource(h); } else { // resource does not exist h = DmNewResource(PrefsDB, 'dflt', which, sizeNeeded); p = MemHandleLock(h); DmWrite(p, 0, value, sizeNeeded); MemHandleUnlock(h); DmReleaseResource(h); } }