/* ** Remember the URL and password if requested. */ void url_remember(void){ if( g.url.flags & URL_REMEMBER ){ db_set("last-sync-url", g.url.canonical, 0); if( g.url.user!=0 && g.url.passwd!=0 && ( g.url.flags & URL_REMEMBER_PW ) ){ db_set("last-sync-pw", obscure(g.url.passwd), 0); } } }
int db_set_int(const char*key, int intval) { aroop_txt_t valstr = {}; aroop_txt_embeded_stackbuffer(&valstr, 32); aroop_txt_printf(&valstr, "%d", intval); aroop_txt_zero_terminate(&valstr); return db_set(key, aroop_txt_to_string(&valstr)); }
int replaceSetting(HWND hwnd, HANDLE hContact, const char *module, const char *setting, DBVARIANT *dbv, const char *find, const char *replace, int mode) { char *szSetting; ptrA myreplace; int count = 0; DBVARIANT dbv2; if (!dbv->type) return 0; if (mode & RW_FULL) szSetting = (char*)replace; else { myreplace = multiReplace(setting, find, replace, mode & RW_CASE); szSetting = myreplace; } if (szSetting[0] == 0) { ItemFound(hwnd, hContact, module, setting, NULL, FW_SETTINGNAME | FW_DELETED); db_unset(hContact, module, setting); return 1; } // check & write if (GetSetting(hContact, module, myreplace, &dbv2)) { if (!db_set(hContact, module, szSetting, &dbv2)) { count++; db_unset(hContact, module, setting); ItemFound(hwnd, hContact, module, szSetting, NULL, FW_SETTINGNAME | FW_REPLACED); } } else db_free(&dbv2); return count; }
void ShiftTipperSettings(LPSTR buff, int count, LPSTR format) { for (int i = count; i > 0; i--) { DBVARIANT dbv; sprintf(buff, format, i - 1); //!!!!!!!!!!!!!!! if (db_get(0, TIPPER_ITEMS_MOD_NAME, buff, &dbv)) break; __try { if (DBVT_ASCIIZ == dbv.type) { db_free(&dbv); if (db_get_ws(0, TIPPER_ITEMS_MOD_NAME, buff, &dbv)) break; } if (db_get_s(0, TIPPER_ITEMS_MOD_NAME, buff, &dbv)) break; sprintf(buff, format, i); //!!!!!!!!!!!!!!!! db_set(NULL, TIPPER_ITEMS_MOD_NAME, buff, &dbv); } __finally { db_free(&dbv); } } }
/* * ulcase -- * Change part of a line's case. */ static int ulcase(SCR *sp, db_recno_t lno, CHAR_T *lp, size_t len, size_t scno, size_t ecno) { size_t blen; int change, rval; ARG_CHAR_T ch; CHAR_T *p, *t, *bp; GET_SPACE_RETW(sp, bp, blen, len); MEMMOVEW(bp, lp, len); change = rval = 0; for (p = bp + scno, t = bp + ecno + 1; p < t; ++p) { ch = (UCHAR_T)*p; if (ISLOWER(ch)) { *p = TOUPPER(ch); change = 1; } else if (ISUPPER(ch)) { *p = TOLOWER(ch); change = 1; } } if (change && db_set(sp, lno, bp, len)) rval = 1; FREE_SPACEW(sp, bp, blen); return (rval); }
static int lua_WriteSetting(lua_State *L) { MCONTACT hContact = lua_tointeger(L, 1); LPCSTR szModule = luaL_checkstring(L, 2); LPCSTR szSetting = luaL_checkstring(L, 3); DBVARIANT dbv = { 0 }; int type = lua_type(L, 4); switch (type) { case LUA_TBOOLEAN: dbv.bVal = lua_toboolean(L, 4); dbv.type = DBVT_BYTE; break; case LUA_TNUMBER: dbv.dVal = lua_tonumber(L, 4); dbv.type = DBVT_DWORD; break; case LUA_TSTRING: dbv.pszVal = (char*)lua_tostring(L, 4); dbv.type = DBVT_UTF8; break; default: lua_pushinteger(L, 1); return 1; } INT_PTR res = db_set(hContact, szModule, szSetting, &dbv); lua_pushinteger(L, res); return 1; }
void do_bench(struct nessdb *db, struct random *rnd, uint32_t loop) { uint32_t i; int done = 0;; int next_report = 100; char kbuf[KEY_SIZE]; for (i = 0; i < loop; i++) { uint32_t krnd = rnd_next(rnd); snprintf(kbuf, KEY_SIZE, "%016d", krnd); char *vbuf = rnd_str(rnd, VAL_SIZE); struct msg k = {.data = kbuf, .size = KEY_SIZE}; struct msg v = {.data = vbuf, .size = VAL_SIZE}; db_set(db, &k, &v); done++; if (done >= next_report) { if (next_report < 1000) next_report += 100; else if (next_report < 5000) next_report += 500; else if (next_report < 10000) next_report += 1000; else if (next_report < 50000) next_report += 5000; else if (next_report < 100000) next_report += 10000; else if (next_report < 500000) next_report += 50000; else next_report += 100000; fprintf(stderr, "random write finished %d ops%30s\r", done, ""); fflush(stderr); } } }
/* ** Common implementation for the ticket setup editor pages. */ static void tktsetup_generic( const char *zTitle, /* Page title */ const char *zDbField, /* Configuration field being edited */ const char *zDfltValue, /* Default text value */ const char *zDesc, /* Description of this field */ char *(*xText)(const char*), /* Validity test or NULL */ void (*xRebuild)(void), /* Run after successful update */ int height /* Height of the edit box */ ){ const char *z; int isSubmit; login_check_credentials(); if( !g.perm.Setup ){ login_needed(0); return; } if( PB("setup") ){ cgi_redirect("tktsetup"); } isSubmit = P("submit")!=0; z = P("x"); if( z==0 ){ z = db_get(zDbField, (char*)zDfltValue); } style_header("Edit %s", zTitle); if( P("clear")!=0 ){ login_verify_csrf_secret(); db_unset(zDbField, 0); if( xRebuild ) xRebuild(); cgi_redirect("tktsetup"); }else if( isSubmit ){ char *zErr = 0; login_verify_csrf_secret(); if( xText && (zErr = xText(z))!=0 ){ cgi_printf("<p class=\"tktsetupError\">ERROR: %h</p>\n",(zErr)); }else{ db_set(zDbField, z, 0); if( xRebuild ) xRebuild(); cgi_redirect("tktsetup"); } } cgi_printf("<form action=\"%s/%s\" method=\"post\"><div>\n",(g.zTop),(g.zPath)); login_insert_csrf_secret(); cgi_printf("<p>%s</p>\n" "<textarea name=\"x\" rows=\"%d\" cols=\"80\">%h</textarea>\n" "<blockquote><p>\n" "<input type=\"submit\" name=\"submit\" value=\"Apply Changes\" />\n" "<input type=\"submit\" name=\"clear\" value=\"Revert To Default\" />\n" "<input type=\"submit\" name=\"setup\" value=\"Cancel\" />\n" "</p></blockquote>\n" "</div></form>\n" "<hr />\n" "<h2>Default %s</h2>\n" "<blockquote><pre>\n" "%h\n" "</pre></blockquote>\n",(zDesc),(height),(z),(zTitle),(zDfltValue)); style_footer(); }
void SaveNotificationSettings(POPUPTREEDATA *ptd, char* szModul) { if (ptd->typ == 1) { char setting[2 * MAXMODULELABELLENGTH]; mir_snprintf(setting, "{%s/%s}Timeout", ptd->notification.lpzGroup, ptd->notification.lpzName); db_set_w(NULL, szModul, setting, ptd->notification.iSeconds); mir_snprintf(setting, "{%s/%s}enabled", ptd->notification.lpzGroup, ptd->notification.lpzName); db_set_b(NULL, szModul, setting, ptd->enabled); mir_snprintf(setting, "{%s/%s}TimeoutVal", ptd->notification.lpzGroup, ptd->notification.lpzName); db_set_w(NULL, szModul, setting, ptd->timeoutValue); mir_snprintf(setting, "{%s/%s}disableWhen", ptd->notification.lpzGroup, ptd->notification.lpzName); db_set_b(NULL, szModul, setting, ptd->disableWhen); mir_snprintf(setting, "{%s/%s}leftAction", ptd->notification.lpzGroup, ptd->notification.lpzName); db_set_s(NULL, szModul, setting, ptd->leftAction); mir_snprintf(setting, "{%s/%s}rightAction", ptd->notification.lpzGroup, ptd->notification.lpzName); db_set_s(NULL, szModul, setting, ptd->rightAction); for (int i = 0; i < ptd->notification.actionCount; ++i) { POPUPNOTIFYACTION &p = ptd->notification.lpActions[i]; if (!mir_strcmp(ptd->leftAction, p.lpzTitle)) db_set(NULL, p.lpzLModule, p.lpzLSetting, &p.dbvLData); if (!mir_strcmp(ptd->rightAction, p.lpzTitle)) db_set(NULL, p.lpzRModule, p.lpzRSetting, &p.dbvRData); } } }
static int EnumProc(const char *szSetting, LPARAM lParam) { EnumProcParam* param = (EnumProcParam*)lParam; DBVARIANT dbv; if (!db_get(NULL, param->szModule, szSetting, &dbv)) { db_set(NULL, param->szNewModule, szSetting, &dbv); db_free(&dbv); } return 0; }
int main(int argc, char **argv) { int i, c; char *optvalue = NULL; char *p, *line, *cfg_file; db_list_t *list; struct passwd *pwdent; pwdent = getpwuid(getuid()); cfg_file = (char *) malloc(strlen(pwdent->pw_dir) + 5); snprintf(cfg_file, strlen(pwdent->pw_dir) + 9, "%s/.locker", pwdent->pw_dir); if (cfg_init(cfg_file, &cfg) < 0) { fprintf(stderr, "could not open config file\n"); return EXIT_FAILURE; } if (!db_init(cfg.db_file)) { fprintf(stderr, "cound not init db\n"); return EXIT_FAILURE; } while ((c = getopt(argc, argv, "a:s:p:c:")) != -1) { switch (c) { case 'a': optvalue = optarg; db_list(optvalue, db_list_callback); break; case 's': optvalue = optarg; printf("password:"******""); db_set(optvalue, encrypt_text(line, cfg.gpg_key)); break; case 'p': optvalue = optarg; db_get(optvalue, db_get_callback); break; default: fprintf(stderr, "Usage:\n\t-s <name>\tSet password\n\t-p <name>\tPrint decrypted password\n\t-a <prefix>\tList all names\n"); } } db_close(); return EXIT_SUCCESS; }
/** * name: toDB * class: CExImContactBase * desc: searches the database for a contact representing the one * identified by this class or creates a new one if it was not found * param: hMetaContact - a meta contact to add this contact to * return: handle of the contact if successful **/ HANDLE CExImContactBase::toDB() { // create new contact if none exists if (_hContact == INVALID_HANDLE_VALUE && _pszProto && _pszUIDKey && _dbvUID.type != DBVT_DELETED) { PROTOACCOUNT* pszAccount = 0; if (NULL == (pszAccount = ProtoGetAccount( _pszProto ))) { //account does not exist _hContact = INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE; } if (!IsAccountEnabled(pszAccount)) { ; } // create new contact _hContact = DB::Contact::Add(); if (!_hContact) { _hContact = INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE; } // Add the protocol to the new contact if (CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)_hContact, (LPARAM)_pszProto)) { DB::Contact::Delete(_hContact); _hContact = INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE; } // write uid to protocol module if (db_set(_hContact, _pszProto, _pszUIDKey, &_dbvUID)) { DB::Contact::Delete(_hContact); _hContact = INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE; } // write nick and display name if (_pszNick) db_set_utf(_hContact, _pszProto, SET_CONTACT_NICK, _pszNick); if (_pszDisp) db_set_utf(_hContact, MOD_CLIST, SET_CONTACT_MYHANDLE, _pszDisp); // add group if (_pszGroup) { ptrT ptszGroup( mir_utf8decodeT(_pszGroup)); db_set_ts(_hContact, MOD_CLIST, "Group", ptszGroup); if ( Clist_GroupExists(ptszGroup) == NULL) { HANDLE hGroup = Clist_CreateGroup(NULL, NULL); if (hGroup) { // renaming twice is stupid but the only way to avoid error dialog telling shit like // a group with that name does exist CallService(MS_CLIST_GROUPRENAME, (WPARAM)hGroup, (LPARAM)ptszGroup); } } } } return _hContact; }
void dbwrite(char *name, int random) { LOG; uint32_t i; int done = 0;; int next_report = 100; char kbuf[KEY_SIZE]; for (i = 0; i < FLAGS_num; i++) { printf("current_%d\n", i); char *vbuf; int key = random ? rand() : i; printf("%016d\n", key); memset(kbuf, 0, KEY_SIZE); snprintf(kbuf, KEY_SIZE, "%016d", key); printf("%s\n", kbuf); vbuf = rnd_str(rnd, VAL_SIZE); struct msg k = {.data = kbuf, .size = strlen(kbuf)}; struct msg v = {.data = vbuf, .size = VAL_SIZE}; if (db_set(db, &k, &v) != NESS_OK) { fprintf(stderr, " set error\n"); } done++; if (done >= next_report) { if (next_report < 1000) next_report += 100; else if (next_report < 5000) next_report += 500; else if (next_report < 10000) next_report += 1000; else if (next_report < 50000) next_report += 5000; else if (next_report < 100000) next_report += 10000; else if (next_report < 500000) next_report += 50000; else next_report += 100000; fprintf(stderr, "%s finished %d ops%30s\r", name, done, ""); fflush(stderr); } } }
int main() { size_t i; obj *op; db* db = db_create(16); cstr k = cstr_new("1", 1); obj* obj = cstr_obj_create("2"); db_set(db, 0, k, obj); for(i = 0; i < 1; i++) { op = db_get(db, 0, k); obj_decr(op); op = db_get(db, 0, k); obj_decr(op); op = db_get(db, 0, k); obj_decr(op); } return 0; }
static void CheckUpdate() { // already converted? int compat = db_get_b(NULL, "Compatibility", "TabChatFonts", 0); if (compat >= 3) return; if (compat == 0) { LIST<char> szSettings(120); DBCONTACTENUMSETTINGS dbces = { 0 }; dbces.szModule = CHAT_OLDFONTMODULE; dbces.pfnEnumProc = CopyChatSetting; dbces.lParam = (LPARAM)&szSettings; CallService(MS_DB_CONTACT_ENUMSETTINGS, 0, (LPARAM)&dbces); DBVARIANT dbv; for (int i = szSettings.getCount() - 1; i >= 0; i--) { char *p = szSettings[i]; db_get(NULL, CHAT_OLDFONTMODULE, p, &dbv); db_set(NULL, CHATFONT_MODULE, p, &dbv); db_free(&dbv); mir_free(p); } CallService(MS_DB_MODULE_DELETE, 0, (LPARAM)CHAT_OLDFONTMODULE); compat++; } if (compat == 1) { DWORD oldBackColor = db_get_dw(0, FONTMODULE, "BkgColourMUC", SRMSGDEFSET_BKGCOLOUR); db_set_dw(NULL, CHAT_MODULE, "ColorLogBG", oldBackColor); db_unset(0, FONTMODULE, "BkgColourMUC"); compat++; } if (compat == 2) { COLORREF color0 = M.GetDword(CHAT_MODULE, "NickColor2", 0); COLORREF color2 = M.GetDword(CHAT_MODULE, "NickColor0", 0); db_set_dw(NULL, CHAT_MODULE, "NickColor0", color0); db_set_dw(NULL, CHAT_MODULE, "NickColor2", color2); compat++; } db_set_b(NULL, "Compatibility", "TabChatFonts", 3); }
int renameModule(MCONTACT hContact, const char *oldName, const char *newName) { ModuleSettingLL settinglist; if (IsModuleEmpty(hContact, oldName) || !EnumSettings(hContact, oldName, &settinglist)) return 0; int cnt = 0; for (ModSetLinkLinkItem *setting = settinglist.first; setting; setting = setting->next) { DBVARIANT dbv; if (!db_get_s(hContact, oldName, setting->name, &dbv, 0)) { db_set(hContact, newName, setting->name, &dbv); db_unset(hContact, oldName, setting->name); db_free(&dbv); cnt++; } } FreeModuleSettingLL(&settinglist); return cnt; }
static int recover_cmd_set(BinLogRecord *pRecord, BinField *pFullValue) { int group_id; char full_key[FDHT_MAX_FULL_KEY_LEN]; int full_key_len; char *p; //tmp var CHECK_GROUP_ID(pRecord, group_id) if (pRecord->value.length + 5 > pFullValue->size) { p = pFullValue->data; pFullValue->size = pRecord->value.length + 1024; pFullValue->data = (char *)malloc(pFullValue->size); if (pFullValue->data == NULL) { logError("file: "__FILE__", line: %d, " \ "malloc %d bytes fail, " \ "errno: %d, error info: %s", __LINE__, \ pFullValue->size, errno, STRERROR(errno)); pFullValue->data = p; return errno != 0 ? errno : ENOMEM; } free(p); } FDHT_PACK_FULL_KEY(pRecord->key_info, full_key, full_key_len, p) int2buff(pRecord->expires, pFullValue->data); memcpy(pFullValue->data+4, pRecord->value.data, pRecord->value.length); pFullValue->length = 4 + pRecord->value.length; return db_set(g_db_list[group_id], full_key, full_key_len, \ pFullValue->data, pFullValue->length); }
void CEditCtrl::OnApply(MCONTACT hContact, LPCSTR pszProto) { if (_Flags.B.hasChanged) { const char* pszModule = hContact ? _pszModule : pszProto; if (_Flags.B.hasCustom || !hContact) { DWORD cch = GetWindowTextLength(_hwnd); if (cch > 0) { LPTSTR val = (LPTSTR)mir_alloc((cch + 1) * sizeof(TCHAR)); if (GetWindowText(_hwnd, val, cch + 1) > 0) { DBVARIANT dbv; dbv.type = _dbType; switch (_dbType) { case DBVT_BYTE: dbv.bVal = (BYTE)_tcstol(val, NULL, 10); break; case DBVT_WORD: dbv.wVal = (WORD)_tcstol(val, NULL, 10); break; case DBVT_DWORD: dbv.dVal = (DWORD)_tcstol(val, NULL, 10); break; case DBVT_TCHAR: dbv.ptszVal = val; break; default: dbv.type = DBVT_DELETED; } if (dbv.type != DBVT_DELETED) { if (!db_set(hContact, pszModule, _pszSetting, &dbv)) { if (!hContact) { _Flags.B.hasCustom = 0; _Flags.B.hasProto = 1; } _Flags.B.hasChanged = 0; // save new value MIR_FREE(_pszValue); _pszValue = val; val = NULL; } } } MIR_FREE(val); } } if (_Flags.B.hasChanged) { db_unset(hContact, pszModule, _pszSetting); _Flags.B.hasChanged = 0; OnInfoChanged(hContact, pszProto); } InvalidateRect(_hwnd, NULL, TRUE); } }
/* * api_sline -- * Set a line. * * PUBLIC: int api_sline __P((SCR *, db_recno_t, CHAR_T *, size_t)); */ int api_sline(SCR *sp, db_recno_t lno, CHAR_T *line, size_t len) { return (db_set(sp, lno, line, len)); }
void __cdecl FindSettings(LPVOID param) { FindInfo* fi = (FindInfo*)param; HWND hwndParent = GetParent(fi->hwnd); ModuleSettingLL ModuleList, SettingList; ModSetLinkLinkItem *module, *setting; MCONTACT hContact; DBVARIANT dbv = { 0 }; int foundCount = 0, replaceCount = 0, deleteCount = 0; DWORD numsearch = 0, numreplace = 0; int NULLContactDone = 0; if (!fi->search || !EnumModules(&ModuleList)) { fi_free(fi); return; } _T2A search(fi->search); _T2A replace(fi->replace); // skip modules and setting names on unicode search or replace if (IsRealUnicode(fi->search) || IsRealUnicode(fi->replace)) { fi->options &= ~(F_SETNAME | F_MODNAME); fi->options |= F_UNICODE; } if (!(fi->options & F_UNICODE) && (fi->options & F_SETVAL)) { char val[16]; numsearch = strtoul(search, NULL, 10); _ultoa(numsearch, val, 10); if (!mir_strcmp(search, val)) { fi->options |= F_NUMSRCH; // replace numeric values only entirely if (replace && (fi->options & F_ENTIRE)) { numreplace = strtoul(replace, NULL, 10); _ultoa(numreplace, val, 10); if (!replace[0] || !mir_strcmp(replace, val)) fi->options |= F_NUMREPL; } } } SendDlgItemMessage(hwndParent, IDC_SBAR, SB_SETTEXT, 0, (LPARAM)TranslateT("Searching...")); hContact = 0; while (GetWindowLongPtr(GetDlgItem(hwndParent, IDC_SEARCH), GWLP_USERDATA)) { if (!hContact) { if (NULLContactDone) break; else { NULLContactDone = 1; hContact = db_find_first(); } } else hContact = db_find_next(hContact); for (module = ModuleList.first; module; module = module->next) { if (IsModuleEmpty(hContact, module->name)) continue; if (fi->options & (F_SETVAL | F_SETNAME)) { if (!EnumSettings(hContact, module->name, &SettingList)) { fi_free(fi); FreeModuleSettingLL(&ModuleList); return; } for (setting = SettingList.first; setting; setting = setting->next) { dbv.type = 0; if (db_get_s(hContact, module->name, setting->name, &dbv, 0)) continue; // check in settings value if (fi->options & F_SETVAL) { TCHAR *value = NULL; switch(dbv.type) { case DBVT_BYTE: case DBVT_WORD: case DBVT_DWORD: if ((fi->options & F_NUMSRCH) && numsearch == getNumericValue(&dbv)) { TCHAR *val = fi->search; int flag = F_SETVAL; if (fi->options & F_NUMREPL) { if (replace[0]) { db_unset(hContact, module->name, setting->name); flag |= F_DELETED; deleteCount++; } else if (setNumericValue(hContact, module->name, setting->name, numreplace, dbv.type)) { val = fi->replace; flag |= F_REPLACED; replaceCount++; } } ItemFound(fi->hwnd, hContact, module->name, setting->name, val, flag); } break; case DBVT_WCHAR: if (!value) value = mir_u2t(dbv.pwszVal); case DBVT_UTF8: if (!value) value = mir_utf8decodeT(dbv.pszVal); case DBVT_ASCIIZ: if (!value) value = mir_a2t(dbv.pszVal); if (FindMatchT(value, fi->search, fi->options)) { foundCount++; ptrT ptr; TCHAR *newValue = value; int flag = F_SETVAL; if (fi->replace) { newValue = (fi->options & F_ENTIRE) ? fi->replace : ptr = multiReplaceT(value, fi->search, fi->replace, fi->options & F_CASE); // !!!! delete or make empty ? if (!newValue[0]) { db_unset(hContact, module->name, setting->name); flag |= F_DELETED; newValue = value; deleteCount++; } else { #ifdef _UNICODE // save as unicode if needed if (dbv.type != DBVT_ASCIIZ || IsRealUnicode(newValue)) db_set_ws(hContact, module->name, setting->name, newValue); else #endif db_set_s(hContact, module->name, setting->name, _T2A(newValue)); flag |= F_REPLACED; replaceCount++; } } ItemFound(fi->hwnd, hContact, module->name, setting->name, newValue, flag); } mir_free(value); break; } // switch } // check in setting name if ((fi->options & F_SETNAME) && FindMatchA(setting->name, search, fi->options)) { foundCount++; ptrA ptr; char *newSetting = setting->name; int flag = F_SETNAME; if (replace) { newSetting = (fi->options & F_ENTIRE) ? replace : ptr = multiReplaceA(setting->name, search, replace, fi->options & F_CASE); if (!newSetting[0]) { db_unset(hContact, module->name, setting->name); flag |= F_DELETED; newSetting = setting->name; deleteCount++; } else { DBVARIANT dbv2; // skip if exist if (!db_get_s(hContact, module->name, newSetting, &dbv2, 0)) db_free(&dbv2); else if (!db_set(hContact, module->name, newSetting, &dbv)) { db_unset(hContact, module->name, setting->name); flag |= F_REPLACED; replaceCount++; } } } ItemFound(fi->hwnd, hContact, module->name, newSetting, NULL, flag); } db_free(&dbv); } // for(setting) FreeModuleSettingLL(&SettingList); } // check in module name if ((fi->options & F_MODNAME) && FindMatchA(module->name, search, fi->options)) { foundCount++; char *newModule = module->name; int flag = F_MODNAME; ptrA ptr; if (replace) { newModule = (fi->options & F_ENTIRE) ? replace : ptr = multiReplaceA(module->name, search, replace, fi->options & F_CASE); if (!newModule[0]) { deleteModule(hContact, module->name, 0); replaceTreeItem(hContact, module->name, NULL); flag |= F_DELETED; newModule = module->name; deleteCount++; } else if (renameModule(hContact, module->name, newModule)) { replaceTreeItem(hContact, module->name, NULL); flag |= F_REPLACED; replaceCount++; } } ItemFound(fi->hwnd, hContact, newModule, 0, 0, flag); } } // for(module) } TCHAR msg[MSG_SIZE]; mir_sntprintf(msg, TranslateT("Finished. Items found: %d / replaced: %d / deleted: %d"), foundCount, replaceCount, deleteCount); SendDlgItemMessage(hwndParent, IDC_SBAR, SB_SETTEXT, 0, (LPARAM)msg); if (fi->replace) { EnableWindow(GetDlgItem(hwndParent, IDC_SEARCH), 1); SetDlgItemText(hwndParent, IDOK, TranslateT("&Replace")); } else { SetDlgItemText(hwndParent, IDC_SEARCH, TranslateT("&Search")); EnableWindow(GetDlgItem(hwndParent, IDOK), 1); } fi_free(fi); FreeModuleSettingLL(&ModuleList); SetWindowLongPtr(GetDlgItem(hwndParent, IDC_SEARCH), GWLP_USERDATA, 0); EnableWindow(GetDlgItem(hwndParent, IDCANCEL), 1); }
/* * put -- * Put text buffer contents into the file. * * PUBLIC: int put __P((SCR *, CB *, CHAR_T *, MARK *, MARK *, int)); */ int put(SCR *sp, CB *cbp, ARG_CHAR_T *namep, MARK *cp, MARK *rp, int append) { ARG_CHAR_T name; TEXT *ltp, *tp; db_recno_t lno; size_t blen, clen, len; int rval; CHAR_T *bp, *t; CHAR_T *p; if (cbp == NULL) { if (namep == NULL) { cbp = sp->wp->dcbp; if (cbp == NULL) { msgq(sp, M_ERR, "053|The default buffer is empty"); return (1); } } else { name = *namep; CBNAME(sp, cbp, name); if (cbp == NULL) { msgq(sp, M_ERR, "054|Buffer %s is empty", KEY_NAME(sp, name)); return (1); } } } tp = cbp->textq.cqh_first; /* * It's possible to do a put into an empty file, meaning that the cut * buffer simply becomes the file. It's a special case so that we can * ignore it in general. * * !!! * Historically, pasting into a file with no lines in vi would preserve * the single blank line. This is surely a result of the fact that the * historic vi couldn't deal with a file that had no lines in it. This * implementation treats that as a bug, and does not retain the blank * line. * * Historical practice is that the cursor ends at the first character * in the file. */ if (cp->lno == 1) { if (db_last(sp, &lno)) return (1); if (lno == 0) { for (; tp != (void *)&cbp->textq; ++lno, ++sp->rptlines[L_ADDED], tp = tp->q.cqe_next) if (db_append(sp, 1, lno, tp->lb, tp->len)) return (1); rp->lno = 1; rp->cno = 0; return (0); } } /* If a line mode buffer, append each new line into the file. */ if (F_ISSET(cbp, CB_LMODE)) { lno = append ? cp->lno : cp->lno - 1; rp->lno = lno + 1; for (; tp != (void *)&cbp->textq; ++lno, ++sp->rptlines[L_ADDED], tp = tp->q.cqe_next) if (db_append(sp, 1, lno, tp->lb, tp->len)) return (1); rp->cno = 0; (void)nonblank(sp, rp->lno, &rp->cno); return (0); } /* * If buffer was cut in character mode, replace the current line with * one built from the portion of the first line to the left of the * split plus the first line in the CB. Append each intermediate line * in the CB. Append a line built from the portion of the first line * to the right of the split plus the last line in the CB. * * Get the first line. */ lno = cp->lno; if (db_get(sp, lno, DBG_FATAL, &p, &len)) return (1); GET_SPACE_RETW(sp, bp, blen, tp->len + len + 1); t = bp; /* Original line, left of the split. */ if (len > 0 && (clen = cp->cno + (append ? 1 : 0)) > 0) { MEMCPYW(bp, p, clen); p += clen; t += clen; } /* First line from the CB. */ if (tp->len != 0) { MEMCPYW(t, tp->lb, tp->len); t += tp->len; } /* Calculate length left in the original line. */ clen = len == 0 ? 0 : len - (cp->cno + (append ? 1 : 0)); /* * !!! * In the historical 4BSD version of vi, character mode puts within * a single line have two cursor behaviors: if the put is from the * unnamed buffer, the cursor moves to the character inserted which * appears last in the file. If the put is from a named buffer, * the cursor moves to the character inserted which appears first * in the file. In System III/V, it was changed at some point and * the cursor always moves to the first character. In both versions * of vi, character mode puts that cross line boundaries leave the * cursor on the first character. Nvi implements the System III/V * behavior, and expect POSIX.2 to do so as well. */ rp->lno = lno; rp->cno = len == 0 ? 0 : sp->cno + (append && tp->len ? 1 : 0); /* * If no more lines in the CB, append the rest of the original * line and quit. Otherwise, build the last line before doing * the intermediate lines, because the line changes will lose * the cached line. */ if (tp->q.cqe_next == (void *)&cbp->textq) { if (clen > 0) { MEMCPYW(t, p, clen); t += clen; } if (db_set(sp, lno, bp, t - bp)) goto err; if (sp->rptlchange != lno) { sp->rptlchange = lno; ++sp->rptlines[L_CHANGED]; } } else { /* * Have to build both the first and last lines of the * put before doing any sets or we'll lose the cached * line. Build both the first and last lines in the * same buffer, so we don't have to have another buffer * floating around. * * Last part of original line; check for space, reset * the pointer into the buffer. */ ltp = cbp->textq.cqh_last; len = t - bp; ADD_SPACE_RETW(sp, bp, blen, ltp->len + clen); t = bp + len; /* Add in last part of the CB. */ MEMCPYW(t, ltp->lb, ltp->len); if (clen) MEMCPYW(t + ltp->len, p, clen); clen += ltp->len; /* * Now: bp points to the first character of the first * line, t points to the last character of the last * line, t - bp is the length of the first line, and * clen is the length of the last. Just figured you'd * want to know. * * Output the line replacing the original line. */ if (db_set(sp, lno, bp, t - bp)) goto err; if (sp->rptlchange != lno) { sp->rptlchange = lno; ++sp->rptlines[L_CHANGED]; } /* Output any intermediate lines in the CB. */ for (tp = tp->q.cqe_next; tp->q.cqe_next != (void *)&cbp->textq; ++lno, ++sp->rptlines[L_ADDED], tp = tp->q.cqe_next) if (db_append(sp, 1, lno, tp->lb, tp->len)) goto err; if (db_append(sp, 1, lno, t, clen)) goto err; ++sp->rptlines[L_ADDED]; } rval = 0; if (0) err: rval = 1; FREE_SPACEW(sp, bp, blen); return (rval); }
/* * del -- * Delete a range of text. * * PUBLIC: int del __P((SCR *, MARK *, MARK *, int)); */ int del( SCR *sp, MARK *fm, MARK *tm, int lmode) { recno_t lno; size_t blen, len, nlen, tlen; CHAR_T *bp, *p; int eof, rval; bp = NULL; /* Case 1 -- delete in line mode. */ if (lmode) { for (lno = tm->lno; lno >= fm->lno; --lno) { if (db_delete(sp, lno)) return (1); ++sp->rptlines[L_DELETED]; if (lno % INTERRUPT_CHECK == 0 && INTERRUPTED(sp)) break; } goto done; } /* * Case 2 -- delete to EOF. This is a special case because it's * easier to pick it off than try and find it in the other cases. */ if (db_last(sp, &lno)) return (1); if (tm->lno >= lno) { if (tm->lno == lno) { if (db_get(sp, lno, DBG_FATAL, &p, &len)) return (1); eof = tm->cno != ENTIRE_LINE && tm->cno >= len ? 1 : 0; } else eof = 1; if (eof) { for (lno = tm->lno; lno > fm->lno; --lno) { if (db_delete(sp, lno)) return (1); ++sp->rptlines[L_DELETED]; if (lno % INTERRUPT_CHECK == 0 && INTERRUPTED(sp)) break; } if (db_get(sp, fm->lno, DBG_FATAL, &p, &len)) return (1); GET_SPACE_RETW(sp, bp, blen, fm->cno); MEMCPY(bp, p, fm->cno); if (db_set(sp, fm->lno, bp, fm->cno)) return (1); goto done; } } /* Case 3 -- delete within a single line. */ if (tm->lno == fm->lno) { if (db_get(sp, fm->lno, DBG_FATAL, &p, &len)) return (1); GET_SPACE_RETW(sp, bp, blen, len); if (fm->cno != 0) MEMCPY(bp, p, fm->cno); MEMCPY(bp + fm->cno, p + (tm->cno + 1), len - (tm->cno + 1)); if (db_set(sp, fm->lno, bp, len - ((tm->cno - fm->cno) + 1))) goto err; goto done; } /* * Case 4 -- delete over multiple lines. * * Copy the start partial line into place. */ if ((tlen = fm->cno) != 0) { if (db_get(sp, fm->lno, DBG_FATAL, &p, NULL)) return (1); GET_SPACE_RETW(sp, bp, blen, tlen + 256); MEMCPY(bp, p, tlen); } /* Copy the end partial line into place. */ if (db_get(sp, tm->lno, DBG_FATAL, &p, &len)) goto err; if (len != 0 && tm->cno != len - 1) { /* * XXX * We can overflow memory here, if the total length is greater * than SIZE_T_MAX. The only portable way I've found to test * is depending on the overflow being less than the value. */ nlen = (len - (tm->cno + 1)) + tlen; if (tlen > nlen) { msgq(sp, M_ERR, "002|Line length overflow"); goto err; } if (tlen == 0) { GET_SPACE_RETW(sp, bp, blen, nlen); } else ADD_SPACE_RETW(sp, bp, blen, nlen); MEMCPY(bp + tlen, p + (tm->cno + 1), len - (tm->cno + 1)); tlen += len - (tm->cno + 1); } /* Set the current line. */ if (db_set(sp, fm->lno, bp, tlen)) goto err; /* Delete the last and intermediate lines. */ for (lno = tm->lno; lno > fm->lno; --lno) { if (db_delete(sp, lno)) goto err; ++sp->rptlines[L_DELETED]; if (lno % INTERRUPT_CHECK == 0 && INTERRUPTED(sp)) break; } done: rval = 0; if (0) err: rval = 1; if (bp != NULL) FREE_SPACEW(sp, bp, blen); return (rval); }
/* * v_replace -- [count]r<char> * * !!! * The r command in historic vi was almost beautiful in its badness. For * example, "r<erase>" and "r<word erase>" beeped the terminal and deleted * a single character. "Nr<carriage return>", where N was greater than 1, * inserted a single carriage return. "r<escape>" did cancel the command, * but "r<literal><escape>" erased a single character. To enter a literal * <literal> character, it required three <literal> characters after the * command. This may not be right, but at least it's not insane. * * PUBLIC: int v_replace __P((SCR *, VICMD *)); */ int v_replace(SCR *sp, VICMD *vp) { EVENT ev; VI_PRIVATE *vip; TEXT *tp; size_t blen, len; u_long cnt; int quote, rval; CHAR_T *bp; CHAR_T *p; vip = VIP(sp); /* * If the line doesn't exist, or it's empty, replacement isn't * allowed. It's not hard to implement, but: * * 1: It's historic practice (vi beeped before the replacement * character was even entered). * 2: For consistency, this change would require that the more * general case, "Nr", when the user is < N characters from * the end of the line, also work, which would be a bit odd. * 3: Replacing with a <newline> has somewhat odd semantics. */ if (db_get(sp, vp->m_start.lno, DBG_FATAL, &p, &len)) return (1); if (len == 0) { msgq(sp, M_BERR, "186|No characters to replace"); return (1); } /* * Figure out how many characters to be replace. For no particular * reason (other than that the semantics of replacing the newline * are confusing) only permit the replacement of the characters in * the current line. I suppose we could append replacement characters * to the line, but I see no compelling reason to do so. Check this * before we get the character to match historic practice, where Nr * failed immediately if there were less than N characters from the * cursor to the end of the line. */ cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; vp->m_stop.lno = vp->m_start.lno; vp->m_stop.cno = vp->m_start.cno + cnt - 1; if (vp->m_stop.cno > len - 1) { v_eol(sp, &vp->m_start); return (1); } /* * If it's not a repeat, reset the current mode and get a replacement * character. */ quote = 0; if (!F_ISSET(vp, VC_ISDOT)) { sp->showmode = SM_REPLACE; if (vs_refresh(sp, 0)) return (1); next: if (v_event_get(sp, &ev, 0, 0)) return (1); switch (ev.e_event) { case E_CHARACTER: /* * <literal_next> means escape the next character. * <escape> means they changed their minds. */ if (!quote) { if (ev.e_value == K_VLNEXT) { quote = 1; goto next; } if (ev.e_value == K_ESCAPE) return (0); } vip->rlast = ev.e_c; vip->rvalue = ev.e_value; break; case E_ERR: case E_EOF: F_SET(sp, SC_EXIT_FORCE); return (1); case E_INTERRUPT: /* <interrupt> means they changed their minds. */ return (0); case E_WRESIZE: /* <resize> interrupts the input mode. */ v_emsg(sp, NULL, VIM_WRESIZE); return (0); case E_REPAINT: if (vs_repaint(sp, &ev)) return (1); goto next; default: v_event_err(sp, &ev); return (0); } } /* Copy the line. */ GET_SPACE_RETW(sp, bp, blen, len); MEMMOVE(bp, p, len); p = bp; /* * Versions of nvi before 1.57 created N new lines when they replaced * N characters with <carriage-return> or <newline> characters. This * is different from the historic vi, which replaced N characters with * a single new line. Users complained, so we match historic practice. */ if ((!quote && vip->rvalue == K_CR) || vip->rvalue == K_NL) { /* Set return line. */ vp->m_stop.lno = vp->m_start.lno + 1; vp->m_stop.cno = 0; /* The first part of the current line. */ if (db_set(sp, vp->m_start.lno, p, vp->m_start.cno)) goto err_ret; /* * The rest of the current line. And, of course, now it gets * tricky. If there are characters left in the line and if * the autoindent edit option is set, white space after the * replaced character is discarded, autoindent is applied, and * the cursor moves to the last indent character. */ p += vp->m_start.cno + cnt; len -= vp->m_start.cno + cnt; if (len != 0 && O_ISSET(sp, O_AUTOINDENT)) for (; len && isblank(*p); --len, ++p); if ((tp = text_init(sp, p, len, len)) == NULL) goto err_ret; if (len != 0 && O_ISSET(sp, O_AUTOINDENT)) { if (v_txt_auto(sp, vp->m_start.lno, NULL, 0, tp)) goto err_ret; vp->m_stop.cno = tp->ai ? tp->ai - 1 : 0; } else vp->m_stop.cno = 0; vp->m_stop.cno = tp->ai ? tp->ai - 1 : 0; if (db_append(sp, 1, vp->m_start.lno, tp->lb, tp->len)) err_ret: rval = 1; else { text_free(tp); rval = 0; } } else { STRSET(bp + vp->m_start.cno, vip->rlast, cnt); rval = db_set(sp, vp->m_start.lno, bp, len); } FREE_SPACEW(sp, bp, blen); vp->m_final = vp->m_stop; return (rval); }
int db_init ( FF_STD_ARGS_PTR std_args, DATA_BIN_HANDLE dbin_h, int (*error_cb)(int) ) { FORMAT_DATA_LIST format_data_list = NULL; int error = 0; int num_errors = 0; assert(dbin_h); if (!dbin_h) return(err_push(ERR_API, "NULL DATA_BIN_HANDLE in %s", ROUTINE_NAME)); if (!*dbin_h) { *dbin_h = db_make(std_args->input_file ? std_args->input_file : "Application Program"); if (!*dbin_h) return(err_push(ERR_MEM_LACK, "Standard Data Bin")); } /* Now set the formats and the auxillary files */ if (db_set(*dbin_h, DBSET_READ_EQV, std_args->input_file)) { err_push(ERR_SET_DBIN, "making name table for %s", std_args->input_file); return(DBSET_READ_EQV); } if (db_set(*dbin_h, DBSET_INPUT_FORMATS, std_args->input_file, std_args->output_file, std_args->input_format_file, std_args->input_format_buffer, std_args->input_format_title, &format_data_list ) ) { if (format_data_list) dll_free_holdings(format_data_list); err_push(ERR_SET_DBIN, "setting an input format for %s", std_args->input_file); return(DBSET_INPUT_FORMATS); } num_errors = err_count(); if (db_set(*dbin_h, DBSET_OUTPUT_FORMATS, std_args->input_file, std_args->output_file, std_args->output_format_file, std_args->output_format_buffer, std_args->output_format_title, &format_data_list ) ) { if (!error_cb || (*error_cb)(DBSET_OUTPUT_FORMATS)) { dll_free_holdings(format_data_list); err_push(ERR_SET_DBIN, "setting an output format for %s", std_args->input_file); return(DBSET_OUTPUT_FORMATS); } else { while (err_count() > num_errors) err_pop(); } } error = db_set(*dbin_h, DBSET_CREATE_CONDUITS, std_args, format_data_list); dll_free_holdings(format_data_list); if (error) { err_push(ERR_SET_DBIN, "creating array information for %s", std_args->input_file); return(DBSET_CREATE_CONDUITS); } /* Check for variable file */ if (std_args->var_file) { FORMAT_DATA_PTR output_fd = fd_get_data(*dbin_h, FFF_OUTPUT); if (IS_ARRAY(output_fd->format)) { err_push(ERR_SET_DBIN, "Cannot use variable file with arrays"); return(DBSET_VARIABLE_RESTRICTION); } if (db_set(*dbin_h, DBSET_VARIABLE_RESTRICTION, std_args->var_file, output_fd->format)) { err_push(ERR_SET_DBIN, "Unable to use variable file \"%s\"", std_args->var_file); return(DBSET_VARIABLE_RESTRICTION); } } if (db_set(*dbin_h, DBSET_EQUATION_VARIABLES)) { err_push(ERR_SET_DBIN, "setting equation variables for %s", std_args->input_file); return(DBSET_EQUATION_VARIABLES); } if (db_set(*dbin_h, DBSET_HEADER_FILE_NAMES, FFF_INPUT, std_args->input_file)) { err_push(ERR_SET_DBIN, "Determining input header file names for %s", std_args->input_file); return(DBSET_HEADER_FILE_NAMES); } num_errors = err_count(); if (db_set(*dbin_h, DBSET_HEADER_FILE_NAMES, FFF_OUTPUT, std_args->output_file)) { if (!error_cb || (*error_cb)(DBSET_OUTPUT_FORMATS)) { err_push(ERR_SET_DBIN, "Determining output header file names for %s", std_args->output_file); return(DBSET_HEADER_FILE_NAMES); } else { while (err_count() > num_errors) err_pop(); } } if (db_set(*dbin_h, DBSET_BYTE_ORDER, FFF_INPUT | FFF_HEADER)) { err_push(ERR_SET_DBIN, "Defining input data byte order"); return(DBSET_BYTE_ORDER); } if (db_set(*dbin_h, DBSET_HEADERS)) { err_push(ERR_SET_DBIN, "getting header file for %s", std_args->input_file); return(DBSET_HEADERS); } if (db_set(*dbin_h, DBSET_USER_UPDATE_FORMATS)) { err_push(ERR_SET_DBIN, "user update of a format for %s", std_args->input_file); return(DBSET_USER_UPDATE_FORMATS); } if (db_set(*dbin_h, DBSET_BYTE_ORDER, FFF_INPUT)) { err_push(ERR_SET_DBIN, "Defining input data byte order"); return(DBSET_BYTE_ORDER); } num_errors = err_count(); if (db_set(*dbin_h, DBSET_BYTE_ORDER, FFF_OUTPUT)) { if (!error_cb || (*error_cb)(DBSET_OUTPUT_FORMATS)) { err_push(ERR_SET_DBIN, "Defining output data byte order"); return(DBSET_BYTE_ORDER); } else { while (err_count() > num_errors) err_pop(); } } if (std_args->cache_size == 0) std_args->cache_size = DEFAULT_CACHE_SIZE; /* Check for query file */ if (std_args->query_file) { if (db_set(*dbin_h, DBSET_QUERY_RESTRICTION, std_args->query_file)) { err_push(ERR_GEN_QUERY, "setting query using %s", std_args->query_file); return(DBSET_QUERY_RESTRICTION); } } if (db_set(*dbin_h, DBSET_INIT_CONDUITS, FFF_DATA, std_args->records_to_read)) { err_push(ERR_SET_DBIN, "creating array information for %s", std_args->input_file); return(DBSET_INIT_CONDUITS); } if (error) return(error); error = merge_redundant_conduits((*dbin_h)->array_conduit_list); if (error) return(error); if (fd_get_data(*dbin_h, FFF_INPUT) && db_set(*dbin_h, DBSET_CACHE_SIZE, std_args->cache_size) ) { return(err_push(ERR_MEM_LACK, "setting data cache for %s", std_args->input_file)); } if (db_set(*dbin_h, DBSET_FORMAT_MAPPINGS)) { err_push(ERR_SET_DBIN, "mapping input to output formats for %s", std_args->input_file); return(DBSET_FORMAT_MAPPINGS); } error = make_unique_format_titles(*dbin_h); if (error) return ERR_MEM_LACK; num_errors = err_count(); if (db_set(*dbin_h, DBSET_VAR_MINMAX)) { if (!error_cb || (*error_cb)(DBSET_OUTPUT_FORMATS)) { err_push(ERR_SET_DBIN, "setting variable minimums and maximums for %s", std_args->input_file); return(DBSET_VAR_MINMAX); } else { while (err_count() > num_errors) err_pop(); } } error = check_file_access(*dbin_h); if (error) return error; return(error); }
/* ** COMMAND: user ** ** Usage: %fossil user SUBCOMMAND ... ?-R|--repository FILE? ** ** Run various subcommands on users of the open repository or of ** the repository identified by the -R or --repository option. ** ** %fossil user capabilities USERNAME ?STRING? ** ** Query or set the capabilities for user USERNAME ** ** %fossil user default ?USERNAME? ** ** Query or set the default user. The default user is the ** user for command-line interaction. ** ** %fossil user list ** ** List all users known to the repository ** ** %fossil user new ?USERNAME? ?CONTACT-INFO? ?PASSWORD? ** ** Create a new user in the repository. Users can never be ** deleted. They can be denied all access but they must continue ** to exist in the database. ** ** %fossil user password USERNAME ?PASSWORD? ** ** Change the web access password for a user. */ void user_cmd(void){ int n; db_find_and_open_repository(1); if( g.argc<3 ){ usage("capabilities|default|list|new|password ..."); } n = strlen(g.argv[2]); if( n>=2 && strncmp(g.argv[2],"new",n)==0 ){ Blob passwd, login, contact; char *zPw; if( g.argc>=4 ){ blob_init(&login, g.argv[3], -1); }else{ prompt_user("login: "******"SELECT 1 FROM user WHERE login=%B", &login) ){ fossil_fatal("user %b already exists", &login); } if( g.argc>=5 ){ blob_init(&contact, g.argv[4], -1); }else{ prompt_user("contact-info: ", &contact); } if( g.argc>=6 ){ blob_init(&passwd, g.argv[5], -1); }else{ prompt_for_password("password: "******"INSERT INTO user(login,pw,cap,info)" "VALUES(%B,%Q,'v',%B)", &login, zPw, &contact ); free(zPw); }else if( n>=2 && strncmp(g.argv[2],"default",n)==0 ){ user_select(); if( g.argc==3 ){ printf("%s\n", g.zLogin); }else{ if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.argv[3]) ){ fossil_fatal("no such user: %s", g.argv[3]); } if( g.localOpen ){ db_lset("default-user", g.argv[3]); }else{ db_set("default-user", g.argv[3], 0); } } }else if( n>=2 && strncmp(g.argv[2],"list",n)==0 ){ Stmt q; db_prepare(&q, "SELECT login, info FROM user ORDER BY login"); while( db_step(&q)==SQLITE_ROW ){ printf("%-12s %s\n", db_column_text(&q, 0), db_column_text(&q, 1)); } db_finalize(&q); }else if( n>=2 && strncmp(g.argv[2],"password",2)==0 ){ char *zPrompt; int uid; Blob pw; if( g.argc!=4 && g.argc!=5 ) usage("password USERNAME ?NEW-PASSWORD?"); uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", g.argv[3]); if( uid==0 ){ fossil_fatal("no such user: %s", g.argv[3]); } if( g.argc==5 ){ blob_init(&pw, g.argv[4], -1); }else{ zPrompt = mprintf("new passwd for %s: ", g.argv[3]); prompt_for_password(zPrompt, &pw, 1); } if( blob_size(&pw)==0 ){ printf("password unchanged\n"); }else{ char *zSecret = sha1_shared_secret(blob_str(&pw), g.argv[3]); db_multi_exec("UPDATE user SET pw=%Q WHERE uid=%d", zSecret, uid); free(zSecret); } }else if( n>=2 && strncmp(g.argv[2],"capabilities",2)==0 ){ int uid; if( g.argc!=4 && g.argc!=5 ){ usage("user capabilities USERNAME ?PERMISSIONS?"); } uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", g.argv[3]); if( uid==0 ){ fossil_fatal("no such user: %s", g.argv[3]); } if( g.argc==5 ){ db_multi_exec( "UPDATE user SET cap=%Q WHERE uid=%d", g.argv[4], uid ); } printf("%s\n", db_text(0, "SELECT cap FROM user WHERE uid=%d", uid)); }else{ fossil_panic("user subcommand should be one of: " "capabilities default list new password"); } }
int ProcessExtraStatus(DBCONTACTWRITESETTING *cws, MCONTACT hContact) { XSTATUSCHANGE *xsc; STATUSMSGINFO smi = { 0 }; char *szProto = GetContactProto(hContact); smi.hContact = hContact; if (strstr(cws->szSetting, "/mood/") || strstr(cws->szSetting, "/activity/")) { // Jabber mood or activity changed if (!ProtoServiceExists(szProto, JS_PARSE_XMPP_URI)) return 0; char *szSetting; int type; if (strstr(cws->szSetting, "/mood/")) { type = TYPE_JABBER_MOOD; szSetting = "LastJabberMood"; } else { type = TYPE_JABBER_ACTIVITY; szSetting = "LastJabberActivity"; } if (strstr(cws->szSetting, "title")) { smi.compare = CompareStatusMsg(&smi, cws, szSetting); if (smi.compare == COMPARE_SAME) { replaceStrW(smi.newstatusmsg, nullptr); replaceStrW(smi.oldstatusmsg, nullptr); } if (cws->value.type == DBVT_DELETED) db_unset(hContact, "UserOnline", szSetting); else db_set(hContact, "UserOnline", szSetting, &cws->value); xsc = NewXSC(hContact, szProto, type, smi.compare, smi.newstatusmsg, nullptr); ExtraStatusChanged(xsc); } else if (strstr(cws->szSetting, "text")) { char dbSetting[128]; mir_snprintf(dbSetting, "%s%s", szSetting, "Msg"); smi.compare = CompareStatusMsg(&smi, cws, dbSetting); if (smi.compare == COMPARE_SAME) { replaceStrW(smi.newstatusmsg, nullptr); replaceStrW(smi.oldstatusmsg, nullptr); } if (cws->value.type == DBVT_DELETED) db_unset(hContact, "UserOnline", dbSetting); else db_set(hContact, "UserOnline", dbSetting, &cws->value); xsc = NewXSC(hContact, szProto, type, smi.compare * 4, nullptr, smi.newstatusmsg); ExtraStatusChanged(xsc); } return 1; } if (strstr(cws->szSetting, "XStatus")) { if (mir_strcmp(cws->szModule, szProto)) return 0; if (mir_strcmp(cws->szSetting, "XStatusName") == 0) { smi.compare = CompareStatusMsg(&smi, cws, "LastXStatusName"); if (smi.compare == COMPARE_SAME) { replaceStrW(smi.newstatusmsg, nullptr); replaceStrW(smi.oldstatusmsg, nullptr); } if (cws->value.type == DBVT_DELETED) db_unset(hContact, "UserOnline", "LastXStatusName"); else db_set(hContact, "UserOnline", "LastXStatusName", &cws->value); xsc = NewXSC(hContact, szProto, TYPE_ICQ_XSTATUS, smi.compare, smi.newstatusmsg, nullptr); ExtraStatusChanged(xsc); } else if (!mir_strcmp(cws->szSetting, "XStatusMsg")) { smi.compare = CompareStatusMsg(&smi, cws, "LastXStatusMsg"); if (smi.compare == COMPARE_SAME) { replaceStrW(smi.newstatusmsg, nullptr); replaceStrW(smi.oldstatusmsg, nullptr); } if (cws->value.type == DBVT_DELETED) db_unset(hContact, "UserOnline", "LastXStatusMsg"); else db_set(hContact, "UserOnline", "LastXStatusMsg", &cws->value); xsc = NewXSC(hContact, szProto, TYPE_ICQ_XSTATUS, smi.compare * 4, nullptr, smi.newstatusmsg); ExtraStatusChanged(xsc); } return 1; } return 0; }
int ProcessStatusMessage(DBCONTACTWRITESETTING *cws, MCONTACT hContact) { STATUSMSGINFO smi; bool bEnablePopup = true, bEnableSound = true; char *szProto = GetContactProto(hContact); smi.proto = szProto; smi.hContact = hContact; smi.compare = CompareStatusMsg(&smi, cws, "LastStatusMsg"); if (smi.compare == COMPARE_SAME) goto skip_notify; if (cws->value.type == DBVT_DELETED) db_unset(hContact, "UserOnline", "LastStatusMsg"); else db_set(hContact, "UserOnline", "LastStatusMsg", &cws->value); //don't show popup when mradio connecting and disconnecting if (_stricmp(szProto, "mRadio") == 0 && !cws->value.type == DBVT_DELETED) { wchar_t buf[MAX_PATH]; mir_snwprintf(buf, L" (%s)", TranslateT("connecting")); T2Utf pszUtf(buf); mir_snwprintf(buf, L" (%s)", TranslateT("aborting")); T2Utf pszUtf2(buf); mir_snwprintf(buf, L" (%s)", TranslateT("playing")); T2Utf pszUtf3(buf); if (_stricmp(cws->value.pszVal, pszUtf) == 0 || _stricmp(cws->value.pszVal, pszUtf2) == 0 || _stricmp(cws->value.pszVal, pszUtf3) == 0) goto skip_notify; } // check per-contact ignored events if (db_get_b(hContact, MODULE, "EnableSMsgNotify", 1) == 0) bEnableSound = bEnablePopup = false; // we're offline or just connecting int myStatus = Proto_GetStatus(szProto); if (myStatus == ID_STATUS_OFFLINE) goto skip_notify; char dbSetting[64]; mir_snprintf(dbSetting, "%s_enabled", szProto); // this proto is not set for status message notifications if (db_get_b(NULL, MODULE, dbSetting, 1) == 0) goto skip_notify; mir_snprintf(dbSetting, "%d", IDC_CHK_STATUS_MESSAGE); // status message change notifications are disabled if (db_get_b(NULL, MODULE, dbSetting, 1) == 0) goto skip_notify; if (SkipHiddenContact(hContact)) goto skip_notify; // check if our status isn't on autodisable list if (opt.AutoDisable) { char statusIDs[12], statusIDp[12]; mir_snprintf(statusIDs, "s%d", myStatus); mir_snprintf(statusIDp, "p%d", myStatus); bEnableSound = db_get_b(0, MODULE, statusIDs, 1) ? FALSE : bEnableSound; bEnablePopup = db_get_b(0, MODULE, statusIDp, 1) ? FALSE : bEnablePopup; } // check flags if ((!(templates.PopupSMsgFlags & NOTIFY_REMOVE_MESSAGE) && (smi.compare == COMPARE_DEL)) || (!(templates.PopupSMsgFlags & NOTIFY_NEW_MESSAGE) && (smi.compare == COMPARE_DIFF))) bEnablePopup = false; if (db_get_b(0, MODULE, szProto, 1) == 0 && !opt.PSMsgOnConnect) bEnablePopup = false; if (bEnablePopup && db_get_b(hContact, MODULE, "EnablePopups", 1) && !opt.TempDisabled) { // cut message if needed wchar_t *copyText = nullptr; if (opt.PSMsgTruncate && (opt.PSMsgLen > 0) && smi.newstatusmsg && (mir_wstrlen(smi.newstatusmsg) > opt.PSMsgLen)) { wchar_t buff[MAX_TEXT_LEN + 3]; copyText = mir_wstrdup(smi.newstatusmsg); wcsncpy(buff, smi.newstatusmsg, opt.PSMsgLen); buff[opt.PSMsgLen] = 0; mir_wstrcat(buff, L"..."); replaceStrW(smi.newstatusmsg, buff); } wchar_t *str; if (smi.compare == COMPARE_DEL) { char protoname[MAX_PATH]; mir_snprintf(protoname, "%s_TPopupSMsgRemoved", szProto); DBVARIANT dbVar = { 0 }; if (db_get_ws(NULL, MODULE, protoname, &dbVar)) { str = GetStr(&smi, DEFAULT_POPUP_SMSGREMOVED); } else { str = GetStr(&smi, dbVar.ptszVal); db_free(&dbVar); } } else { char protoname[MAX_PATH]; mir_snprintf(protoname, "%s_TPopupSMsgChanged", szProto); DBVARIANT dbVar = { 0 }; if (db_get_ws(NULL, MODULE, protoname, &dbVar)) { str = GetStr(&smi, DEFAULT_POPUP_SMSGCHANGED); } else { str = GetStr(&smi, dbVar.ptszVal); db_free(&dbVar); } } ShowChangePopup(hContact, Skin_LoadProtoIcon(szProto, db_get_w(hContact, szProto, "Status", ID_STATUS_ONLINE)), ID_STATUS_STATUSMSG, str); mir_free(str); if (copyText) { mir_free(smi.newstatusmsg); smi.newstatusmsg = copyText; } } if (opt.BlinkIcon && opt.BlinkIcon_ForMsgs && !opt.TempDisabled) { HICON hIcon = opt.BlinkIcon_Status ? Skin_LoadProtoIcon(szProto, db_get_w(hContact, szProto, "Status", ID_STATUS_ONLINE)) : Skin_LoadIcon(SKINICON_OTHER_USERONLINE); wchar_t str[256]; mir_snwprintf(str, TranslateT("%s changed status message to %s"), Clist_GetContactDisplayName(hContact), smi.newstatusmsg); BlinkIcon(hContact, hIcon, str); } if (bEnableSound && db_get_b(0, "Skin", "UseSound", TRUE) && db_get_b(hContact, MODULE, "EnableSounds", 1) && !opt.TempDisabled) { if (smi.compare == COMPARE_DEL) PlayChangeSound(hContact, StatusListEx[ID_STATUS_SMSGREMOVED].lpzSkinSoundName); else PlayChangeSound(hContact, StatusListEx[ID_STATUS_SMSGCHANGED].lpzSkinSoundName); } BOOL bEnableLog = opt.SMsgLogToDB && db_get_b(hContact, MODULE, "EnableSMsgLogging", 1); if (bEnableLog && (!opt.SMsgLogToDB_WinOpen || CheckMsgWnd(hContact))) LogSMsgToDB(&smi, smi.compare == COMPARE_DEL ? templates.LogSMsgRemoved : templates.LogSMsgChanged); if (opt.SMsgLogToFile && db_get_b(hContact, MODULE, "EnableSMsgLogging", 1)) { wchar_t stzDate[MAX_STATUSTEXT], stzTime[MAX_STATUSTEXT], stzText[MAX_TEXT_LEN]; GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"HH':'mm", stzTime, _countof(stzTime)); GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"dd/MM/yyyy", stzDate, _countof(stzDate)); wchar_t *str; if (smi.compare == COMPARE_DEL) str = GetStr(&smi, templates.LogSMsgRemoved); else str = GetStr(&smi, templates.LogSMsgChanged); mir_snwprintf(stzText, L"%s, %s. %s %s\r\n", stzDate, stzTime, Clist_GetContactDisplayName(hContact), str); LogToFile(stzText); mir_free(str); } skip_notify: replaceStrW(smi.newstatusmsg, nullptr); replaceStrW(smi.oldstatusmsg, nullptr); return 1; }
static int s(SCR *sp, EXCMD *cmdp, char *s, regex_t *re, u_int flags) { EVENT ev; MARK from, to; TEXTH tiq; recno_t elno, lno, slno; regmatch_t match[10]; size_t blen, cnt, last, lbclen, lblen, len, llen; size_t offset, saved_offset, scno; int lflag, nflag, pflag, rflag; int didsub, do_eol_match, eflags, empty_ok, eval; int linechanged, matched, quit, rval; unsigned long ul; char *bp, *lb; NEEDFILE(sp, cmdp); slno = sp->lno; scno = sp->cno; /* * !!! * Historically, the 'g' and 'c' suffices were always toggled as flags, * so ":s/A/B/" was the same as ":s/A/B/ccgg". If O_EDCOMPATIBLE was * not set, they were initialized to 0 for all substitute commands. If * O_EDCOMPATIBLE was set, they were initialized to 0 only if the user * specified substitute/replacement patterns (see ex_s()). */ if (!O_ISSET(sp, O_EDCOMPATIBLE)) sp->c_suffix = sp->g_suffix = 0; /* * Historic vi permitted the '#', 'l' and 'p' options in vi mode, but * it only displayed the last change. I'd disallow them, but they are * useful in combination with the [v]global commands. In the current * model the problem is combining them with the 'c' flag -- the screen * would have to flip back and forth between the confirm screen and the * ex print screen, which would be pretty awful. We do display all * changes, though, for what that's worth. * * !!! * Historic vi was fairly strict about the order of "options", the * count, and "flags". I'm somewhat fuzzy on the difference between * options and flags, anyway, so this is a simpler approach, and we * just take it them in whatever order the user gives them. (The ex * usage statement doesn't reflect this.) */ lflag = nflag = pflag = rflag = 0; if (s == NULL) goto noargs; for (lno = OOBLNO; *s != '\0'; ++s) switch (*s) { case ' ': case '\t': continue; case '+': ++cmdp->flagoff; break; case '-': --cmdp->flagoff; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (lno != OOBLNO) goto usage; errno = 0; if ((ul = strtoul(s, &s, 10)) >= UINT_MAX) errno = ERANGE; if (*s == '\0') /* Loop increment correction. */ --s; if (errno == ERANGE) { if (ul >= UINT_MAX) msgq(sp, M_ERR, "Count overflow"); else msgq(sp, M_SYSERR, NULL); return (1); } lno = (recno_t)ul; /* * In historic vi, the count was inclusive from the * second address. */ cmdp->addr1.lno = cmdp->addr2.lno; cmdp->addr2.lno += lno - 1; if (!db_exist(sp, cmdp->addr2.lno) && db_last(sp, &cmdp->addr2.lno)) return (1); break; case '#': nflag = 1; break; case 'c': sp->c_suffix = !sp->c_suffix; /* Ex text structure initialization. */ if (F_ISSET(sp, SC_EX)) { memset(&tiq, 0, sizeof(TEXTH)); TAILQ_INIT(&tiq); } break; case 'g': sp->g_suffix = !sp->g_suffix; break; case 'l': lflag = 1; break; case 'p': pflag = 1; break; case 'r': if (LF_ISSET(SUB_FIRST)) { msgq(sp, M_ERR, "Regular expression specified; r flag meaningless"); return (1); } if (!F_ISSET(sp, SC_RE_SEARCH)) { ex_emsg(sp, NULL, EXM_NOPREVRE); return (1); } rflag = 1; re = &sp->re_c; break; default: goto usage; } if (*s != '\0' || (!rflag && LF_ISSET(SUB_MUSTSETR))) { usage: ex_emsg(sp, cmdp->cmd->usage, EXM_USAGE); return (1); } noargs: if (F_ISSET(sp, SC_VI) && sp->c_suffix && (lflag || nflag || pflag)) { msgq(sp, M_ERR, "The #, l and p flags may not be combined with the c flag in vi mode"); return (1); } /* * bp: if interactive, line cache * blen: if interactive, line cache length * lb: build buffer pointer. * lbclen: current length of built buffer. * lblen; length of build buffer. */ bp = lb = NULL; blen = lbclen = lblen = 0; /* For each line... */ for (matched = quit = 0, lno = cmdp->addr1.lno, elno = cmdp->addr2.lno; !quit && lno <= elno; ++lno) { /* Someone's unhappy, time to stop. */ if (INTERRUPTED(sp)) break; /* Get the line. */ if (db_get(sp, lno, DBG_FATAL, &s, &llen)) goto err; /* * Make a local copy if doing confirmation -- when calling * the confirm routine we're likely to lose the cached copy. */ if (sp->c_suffix) { if (bp == NULL) { GET_SPACE_RET(sp, bp, blen, llen); } else ADD_SPACE_RET(sp, bp, blen, llen); memcpy(bp, s, llen); s = bp; } /* Start searching from the beginning. */ offset = 0; len = llen; /* Reset the build buffer offset. */ lbclen = 0; /* Reset empty match flag. */ empty_ok = 1; /* * We don't want to have to do a setline if the line didn't * change -- keep track of whether or not this line changed. * If doing confirmations, don't want to keep setting the * line if change is refused -- keep track of substitutions. */ didsub = linechanged = 0; /* New line, do an EOL match. */ do_eol_match = 1; /* It's not nul terminated, but we pretend it is. */ eflags = REG_STARTEND; /* * The search area is from s + offset to the EOL. * * Generally, match[0].rm_so is the offset of the start * of the match from the start of the search, and offset * is the offset of the start of the last search. */ nextmatch: match[0].rm_so = 0; match[0].rm_eo = len; /* Get the next match. */ eval = regexec(re, (char *)s + offset, 10, match, eflags); /* * There wasn't a match or if there was an error, deal with * it. If there was a previous match in this line, resolve * the changes into the database. Otherwise, just move on. */ if (eval == REG_NOMATCH) goto endmatch; if (eval != 0) { re_error(sp, eval, re); goto err; } matched = 1; /* Only the first search can match an anchored expression. */ eflags |= REG_NOTBOL; /* * !!! * It's possible to match 0-length strings -- for example, the * command s;a*;X;, when matched against the string "aabb" will * result in "XbXbX", i.e. the matches are "aa", the space * between the b's and the space between the b's and the end of * the string. There is a similar space between the beginning * of the string and the a's. The rule that we use (because vi * historically used it) is that any 0-length match, occurring * immediately after a match, is ignored. Otherwise, the above * example would have resulted in "XXbXbX". Another example is * incorrectly using " *" to replace groups of spaces with one * space. * * The way we do this is that if we just had a successful match, * the starting offset does not skip characters, and the match * is empty, ignore the match and move forward. If there's no * more characters in the string, we were attempting to match * after the last character, so quit. */ if (!empty_ok && match[0].rm_so == 0 && match[0].rm_eo == 0) { empty_ok = 1; if (len == 0) goto endmatch; BUILD(sp, s + offset, 1) ++offset; --len; goto nextmatch; } /* Confirm change. */ if (sp->c_suffix) { /* * Set the cursor position for confirmation. Note, * if we matched on a '$', the cursor may be past * the end of line. */ from.lno = to.lno = lno; from.cno = match[0].rm_so + offset; to.cno = match[0].rm_eo + offset; /* * Both ex and vi have to correct for a change before * the first character in the line. */ if (llen == 0) from.cno = to.cno = 0; if (F_ISSET(sp, SC_VI)) { /* * Only vi has to correct for a change after * the last character in the line. * * XXX * It would be nice to change the vi code so * that we could display a cursor past EOL. */ if (to.cno >= llen) to.cno = llen - 1; if (from.cno >= llen) from.cno = llen - 1; sp->lno = from.lno; sp->cno = from.cno; if (vs_refresh(sp, 1)) goto err; vs_update(sp, "Confirm change? [n]", NULL); if (v_event_get(sp, &ev, 0, 0)) goto err; switch (ev.e_event) { case E_CHARACTER: break; case E_EOF: case E_ERR: case E_INTERRUPT: goto lquit; default: v_event_err(sp, &ev); goto lquit; } } else { if (ex_print(sp, cmdp, &from, &to, 0) || ex_scprint(sp, &from, &to)) goto lquit; if (ex_txt(sp, &tiq, 0, TXT_CR)) goto err; ev.e_c = TAILQ_FIRST(&tiq)->lb[0]; } switch (ev.e_c) { case CH_YES: break; default: case CH_NO: didsub = 0; BUILD(sp, s +offset, match[0].rm_eo); goto skip; case CH_QUIT: /* Set the quit/interrupted flags. */ lquit: quit = 1; F_SET(sp->gp, G_INTERRUPTED); /* * Resolve any changes, then return to (and * exit from) the main loop. */ goto endmatch; } } /* * Set the cursor to the last position changed, converting * from 1-based to 0-based. */ sp->lno = lno; sp->cno = match[0].rm_so; /* Copy the bytes before the match into the build buffer. */ BUILD(sp, s + offset, match[0].rm_so); /* Substitute the matching bytes. */ didsub = 1; if (re_sub(sp, s + offset, &lb, &lbclen, &lblen, match)) goto err; /* Set the change flag so we know this line was modified. */ linechanged = 1; /* Move past the matched bytes. */ skip: offset += match[0].rm_eo; len -= match[0].rm_eo; /* A match cannot be followed by an empty pattern. */ empty_ok = 0; /* * If doing a global change with confirmation, we have to * update the screen. The basic idea is to store the line * so the screen update routines can find it, and restart. */ if (didsub && sp->c_suffix && sp->g_suffix) { /* * The new search offset will be the end of the * modified line. */ saved_offset = lbclen; /* Copy the rest of the line. */ if (len) BUILD(sp, s + offset, len) /* Set the new offset. */ offset = saved_offset; /* Store inserted lines, adjusting the build buffer. */ last = 0; if (sp->newl_cnt) { for (cnt = 0; cnt < sp->newl_cnt; ++cnt, ++lno, ++elno) { if (db_insert(sp, lno, lb + last, sp->newl[cnt] - last)) goto err; last = sp->newl[cnt] + 1; ++sp->rptlines[L_ADDED]; } lbclen -= last; offset -= last; sp->newl_cnt = 0; } /* Store and retrieve the line. */ if (db_set(sp, lno, lb + last, lbclen)) goto err; if (db_get(sp, lno, DBG_FATAL, &s, &llen)) goto err; ADD_SPACE_RET(sp, bp, blen, llen) memcpy(bp, s, llen); s = bp; len = llen - offset; /* Restart the build. */ lbclen = 0; BUILD(sp, s, offset); /* * If we haven't already done the after-the-string * match, do one. Set REG_NOTEOL so the '$' pattern * only matches once. */ if (!do_eol_match) goto endmatch; if (offset == len) { do_eol_match = 0; eflags |= REG_NOTEOL; } goto nextmatch; } /* * If it's a global: * * If at the end of the string, do a test for the after * the string match. Set REG_NOTEOL so the '$' pattern * only matches once. */ if (sp->g_suffix && do_eol_match) { if (len == 0) { do_eol_match = 0; eflags |= REG_NOTEOL; } goto nextmatch; } endmatch: if (!linechanged) continue; /* Copy any remaining bytes into the build buffer. */ if (len) BUILD(sp, s + offset, len) /* Store inserted lines, adjusting the build buffer. */ last = 0; if (sp->newl_cnt) { for (cnt = 0; cnt < sp->newl_cnt; ++cnt, ++lno, ++elno) { if (db_insert(sp, lno, lb + last, sp->newl[cnt] - last)) goto err; last = sp->newl[cnt] + 1; ++sp->rptlines[L_ADDED]; } lbclen -= last; sp->newl_cnt = 0; } /* Store the changed line. */ if (db_set(sp, lno, lb + last, lbclen)) goto err; /* Update changed line counter. */ if (sp->rptlchange != lno) { sp->rptlchange = lno; ++sp->rptlines[L_CHANGED]; } /* * !!! * Display as necessary. Historic practice is to only * display the last line of a line split into multiple * lines. */ if (lflag || nflag || pflag) { from.lno = to.lno = lno; from.cno = to.cno = 0; if (lflag) (void)ex_print(sp, cmdp, &from, &to, E_C_LIST); if (nflag) (void)ex_print(sp, cmdp, &from, &to, E_C_HASH); if (pflag) (void)ex_print(sp, cmdp, &from, &to, E_C_PRINT); } } /* * !!! * Historically, vi attempted to leave the cursor at the same place if * the substitution was done at the current cursor position. Otherwise * it moved it to the first non-blank of the last line changed. There * were some problems: for example, :s/$/foo/ with the cursor on the * last character of the line left the cursor on the last character, or * the & command with multiple occurrences of the matching string in the * line usually left the cursor in a fairly random position. * * We try to do the same thing, with the exception that if the user is * doing substitution with confirmation, we move to the last line about * which the user was consulted, as opposed to the last line that they * actually changed. This prevents a screen flash if the user doesn't * change many of the possible lines. */ if (!sp->c_suffix && (sp->lno != slno || sp->cno != scno)) { sp->cno = 0; (void)nonblank(sp, sp->lno, &sp->cno); } /* * If not in a global command, and nothing matched, say so. * Else, if none of the lines displayed, put something up. */ rval = 0; if (!matched) { if (!F_ISSET(sp, SC_EX_GLOBAL)) { msgq(sp, M_ERR, "No match found"); goto err; } } else if (!lflag && !nflag && !pflag) F_SET(cmdp, E_AUTOPRINT); if (0) { err: rval = 1; } if (bp != NULL) FREE_SPACE(sp, bp, blen); if (lb != NULL) free(lb); return (rval); }
int Meta_SettingChanged(WPARAM hContact, LPARAM lParam) { DBCONTACTWRITESETTING *dcws = (DBCONTACTWRITESETTING *)lParam; char buffer[512]; // the only global options we're interested in if (hContact == 0) return 0; DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact); if (cc == NULL || !cc->IsSub()) return 0; DBCachedContact *ccMeta = currDb->m_cache->GetCachedContact(cc->parentID); if (ccMeta == NULL || !ccMeta->IsMeta()) return 0; // This contact is attached to a MetaContact. int contact_number = Meta_GetContactNumber(ccMeta, hContact); if (contact_number == -1) return 0; // exit - db corruption if (!strcmp(dcws->szSetting, "IP")) { if (dcws->value.type == DBVT_DWORD) db_set_dw(ccMeta->contactID, META_PROTO, "IP", dcws->value.dVal); else db_unset(ccMeta->contactID, META_PROTO, "IP"); } else if (!strcmp(dcws->szSetting, "RealIP")) { if (dcws->value.type == DBVT_DWORD) db_set_dw(ccMeta->contactID, META_PROTO, "RealIP", dcws->value.dVal); else db_unset(ccMeta->contactID, META_PROTO, "RealIP"); } else if (!strcmp(dcws->szSetting, "ListeningTo")) { switch (dcws->value.type) { case DBVT_ASCIIZ: db_set_s(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal); break; case DBVT_UTF8: db_set_utf(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal); break; case DBVT_WCHAR: db_set_ws(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pwszVal); break; case DBVT_DELETED: db_unset(ccMeta->contactID, META_PROTO, "ListeningTo"); break; } } else if (!strcmp(dcws->szSetting, "Nick") && dcws->value.type != DBVT_DELETED) { // subcontact nick has changed - update metacontact mir_snprintf(buffer, SIZEOF(buffer), "Nick%d", contact_number); db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value); ptrT tszMyhandle(db_get_tsa(hContact, "CList", "MyHandle")); if (tszMyhandle == NULL) { mir_snprintf(buffer, SIZEOF(buffer), "CListName%d", contact_number); db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value); } // copy nick to metacontact, if it's the most online MCONTACT hMostOnline = Meta_GetMostOnline(ccMeta); Meta_CopyContactNick(ccMeta, hMostOnline); } else if (!strcmp(dcws->szSetting, "IdleTS")) { if (dcws->value.type == DBVT_DWORD) db_set_dw(ccMeta->contactID, META_PROTO, "IdleTS", dcws->value.dVal); else if (dcws->value.type == DBVT_DELETED) db_set_dw(ccMeta->contactID, META_PROTO, "IdleTS", 0); } else if (!strcmp(dcws->szSetting, "LogonTS")) { if (dcws->value.type == DBVT_DWORD) db_set_dw(ccMeta->contactID, META_PROTO, "LogonTS", dcws->value.dVal); else if (dcws->value.type == DBVT_DELETED) db_set_dw(ccMeta->contactID, META_PROTO, "LogonTS", 0); } else if (!strcmp(dcws->szModule, "CList") && !strcmp(dcws->szSetting, "MyHandle")) { if (dcws->value.type == DBVT_DELETED) { char *proto = GetContactProto(hContact); mir_snprintf(buffer, SIZEOF(buffer), "CListName%d", contact_number); DBVARIANT dbv; if (proto && !db_get_ts(hContact, proto, "Nick", &dbv)) { db_set_ts(ccMeta->contactID, META_PROTO, buffer, dbv.ptszVal); db_free(&dbv); } else db_unset(ccMeta->contactID, META_PROTO, buffer); } else { // subcontact clist displayname has changed - update metacontact mir_snprintf(buffer, SIZEOF(buffer), "CListName%d", contact_number); db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value); } // copy nick to metacontact, if it's the most online Meta_CopyContactNick(ccMeta, Meta_GetMostOnline(ccMeta)); } // subcontact changing status else if (!strcmp(dcws->szSetting, "Status") && dcws->value.type != DBVT_DELETED) { // update subcontact status setting mir_snprintf(buffer, SIZEOF(buffer), "Status%d", contact_number); db_set_w(ccMeta->contactID, META_PROTO, buffer, dcws->value.wVal); mir_snprintf(buffer, SIZEOF(buffer), "StatusString%d", contact_number); db_set_ts(ccMeta->contactID, META_PROTO, buffer, cli.pfnGetStatusModeDescription(dcws->value.wVal, 0)); // set status to that of most online contact MCONTACT hMostOnline = Meta_GetMostOnline(ccMeta); if (hMostOnline != db_mc_getDefault(ccMeta->contactID)) db_mc_notifyDefChange(ccMeta->contactID, hMostOnline); Meta_CopyContactNick(ccMeta, hMostOnline); Meta_FixStatus(ccMeta); // most online contact with avatar support might have changed - update avatar hMostOnline = Meta_GetMostOnlineSupporting(ccMeta, PFLAGNUM_4, PF4_AVATARS); if (hMostOnline) { PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) }; AI.hContact = ccMeta->contactID; AI.format = PA_FORMAT_UNKNOWN; _tcscpy(AI.filename, _T("X")); if (CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) db_set_ts(ccMeta->contactID, "ContactPhoto", "File", AI.filename); } } return 0; }
/* * shift -- * Ex shift support. */ static int shift(SCR *sp, EXCMD *cmdp, enum which rl) { db_recno_t from, to; size_t blen, len, newcol, newidx, oldcol, oldidx, sw; int curset; CHAR_T *p; CHAR_T *bp, *tbp; NEEDFILE(sp, cmdp); if (O_VAL(sp, O_SHIFTWIDTH) == 0) { msgq(sp, M_INFO, "152|shiftwidth option set to 0"); return (0); } /* Copy the lines being shifted into the unnamed buffer. */ if (cut(sp, NULL, &cmdp->addr1, &cmdp->addr2, CUT_LINEMODE)) return (1); /* * The historic version of vi permitted the user to string any number * of '>' or '<' characters together, resulting in an indent of the * appropriate levels. There's a special hack in ex_cmd() so that * cmdp->argv[0] points to the string of '>' or '<' characters. * * Q: What's the difference between the people adding features * to vi and the Girl Scouts? * A: The Girl Scouts have mint cookies and adult supervision. */ for (p = cmdp->argv[0]->bp, sw = 0; *p == '>' || *p == '<'; ++p) sw += O_VAL(sp, O_SHIFTWIDTH); GET_SPACE_RETW(sp, bp, blen, 256); curset = 0; for (from = cmdp->addr1.lno, to = cmdp->addr2.lno; from <= to; ++from) { if (db_get(sp, from, DBG_FATAL, &p, &len)) goto err; if (!len) { if (sp->lno == from) curset = 1; continue; } /* * Calculate the old indent amount and the number of * characters it used. */ for (oldidx = 0, oldcol = 0; oldidx < len; ++oldidx) if (p[oldidx] == ' ') ++oldcol; else if (p[oldidx] == '\t') oldcol += O_VAL(sp, O_TABSTOP) - oldcol % O_VAL(sp, O_TABSTOP); else break; /* Calculate the new indent amount. */ if (rl == RIGHT) newcol = oldcol + sw; else { newcol = oldcol < sw ? 0 : oldcol - sw; if (newcol == oldcol) { if (sp->lno == from) curset = 1; continue; } } /* Get a buffer that will hold the new line. */ ADD_SPACE_RETW(sp, bp, blen, newcol + len); /* * Build a new indent string and count the number of * characters it uses. */ tbp = bp; newidx = 0; if (!O_ISSET(sp, O_EXPANDTAB)) { for (; newcol >= O_VAL(sp, O_TABSTOP); ++newidx) { *tbp++ = '\t'; newcol -= O_VAL(sp, O_TABSTOP); } } for (; newcol > 0; --newcol, ++newidx) *tbp++ = ' '; /* Add the original line. */ MEMCPYW(tbp, p + oldidx, len - oldidx); /* Set the replacement line. */ if (db_set(sp, from, bp, (tbp + (len - oldidx)) - bp)) { err: FREE_SPACEW(sp, bp, blen); return (1); } /* * !!! * The shift command in historic vi had the usual bizarre * collection of cursor semantics. If called from vi, the * cursor was repositioned to the first non-blank character * of the lowest numbered line shifted. If called from ex, * the cursor was repositioned to the first non-blank of the * highest numbered line shifted. Here, if the cursor isn't * part of the set of lines that are moved, move it to the * first non-blank of the last line shifted. (This makes * ":3>>" in vi work reasonably.) If the cursor is part of * the shifted lines, it doesn't get moved at all. This * permits shifting of marked areas, i.e. ">'a." shifts the * marked area twice, something that couldn't be done with * historic vi. */ if (sp->lno == from) { curset = 1; if (newidx > oldidx) sp->cno += newidx - oldidx; else if (sp->cno >= oldidx - newidx) sp->cno -= oldidx - newidx; } } if (!curset) { sp->lno = to; sp->cno = 0; (void)nonblank(sp, to, &sp->cno); } FREE_SPACEW(sp, bp, blen); sp->rptlines[L_SHIFT] += cmdp->addr2.lno - cmdp->addr1.lno + 1; return (0); }