/* * v_yank -- [buffer][count]y[count][motion] * [buffer][count]Y * Yank text (or lines of text) into a cut buffer. * * !!! * Historic vi moved the cursor to the from MARK if it was before the current * cursor and on a different line, e.g., "yk" moves the cursor but "yj" and * "yl" do not. Unfortunately, it's too late to change this now. Matching * the historic semantics isn't easy. The line number was always changed and * column movement was usually relative. However, "y'a" moved the cursor to * the first non-blank of the line marked by a, while "y`a" moved the cursor * to the line and column marked by a. Hopefully, the motion component code * got it right... Unlike delete, we make no adjustments here. * * PUBLIC: int v_yank(SCR *, VICMD *); */ int v_yank(SCR *sp, VICMD *vp) { size_t len; if (cut(sp, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL, &vp->m_start, &vp->m_stop, F_ISSET(vp, VM_LMODE) ? CUT_LINEMODE : 0)) return (1); sp->rptlines[L_YANKED] += (vp->m_stop.lno - vp->m_start.lno) + 1; /* * One special correction, in case we've deleted the current line or * character. We check it here instead of checking in every command * that can be a motion component. */ if (db_get(sp, vp->m_final.lno, DBG_FATAL, NULL, &len)) return (1); /* * !!! * Cursor movements, other than those caused by a line mode command * moving to another line, historically reset the relative position. * * This currently matches the check made in v_delete(), I'm hoping * that they should be consistent... */ if (!F_ISSET(vp, VM_LMODE)) { F_CLR(vp, VM_RCM_MASK); F_SET(vp, VM_RCM_SET); /* Make sure the set cursor position exists. */ if (vp->m_final.cno >= len) vp->m_final.cno = len ? len - 1 : 0; } return (0); }
void CSAMWindow::setCombo() { PROTOACCOUNT *pdescr = Proto_GetAccount(m_parent->m_protoName); if (pdescr == nullptr) return; const char *szUniqueID = Proto_GetUniqueId(pdescr->szModuleName); if (szUniqueID == nullptr) return; DBVARIANT dbv; if (db_get(NULL, pdescr->szModuleName, szUniqueID, &dbv)) return; db_free(&dbv); WPARAM iStatus; wchar_t tszName[100]; CUSTOM_STATUS cs = { sizeof(cs) }; cs.flags = CSSF_MASK_NAME | CSSF_DEFAULT_NAME | CSSF_UNICODE; cs.ptszName = tszName; cs.wParam = &iStatus; SendMessage(m_hCombo, CBEM_SETIMAGELIST, 0, (LPARAM)m_parent->m_icons); for (int i = 1; i <= m_parent->m_statusCount; i++) { iStatus = i; if (CallProtoService(pdescr->szModuleName, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&cs) != 0) continue; COMBOBOXEXITEM cbi = { 0 }; cbi.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE; cbi.iItem = -1; cbi.iImage = cbi.iSelectedImage = i - 1; cbi.pszText = TranslateW(tszName); SendMessage(m_hCombo, CBEM_INSERTITEM, 0, (LPARAM)&cbi); } SendMessage(m_hCombo, CB_SETCURSEL, 0, 0); // first 0 sets selection to top }
/* * cs_next -- * Retrieve the next character. * * PUBLIC: int cs_next __P((SCR *, VCS *)); */ int cs_next(SCR *sp, VCS *csp) { CHAR_T *p; switch (csp->cs_flags) { case CS_EMP: /* EMP; get next line. */ case CS_EOL: /* EOL; get next line. */ if (db_get(sp, ++csp->cs_lno, 0, &p, &csp->cs_len)) { --csp->cs_lno; csp->cs_flags = CS_EOF; } else { csp->cs_bp = p; if (csp->cs_len == 0 || v_isempty(csp->cs_bp, csp->cs_len)) { csp->cs_cno = 0; csp->cs_flags = CS_EMP; } else { csp->cs_flags = 0; csp->cs_ch = csp->cs_bp[csp->cs_cno = 0]; } } break; case 0: if (csp->cs_cno == csp->cs_len - 1) csp->cs_flags = CS_EOL; else csp->cs_ch = csp->cs_bp[++csp->cs_cno]; break; case CS_EOF: /* EOF. */ break; default: abort(); /* NOTREACHED */ } return (0); }
int TlenProtocol::PrebuildContactMenu(WPARAM hContact, LPARAM) { if (hContact != NULL && isOnline) { DBVARIANT dbv; if (!db_get(hContact, m_szModuleName, "jid", &dbv)) { TLEN_LIST_ITEM *item = TlenListGetItemPtr(this, LIST_ROSTER, dbv.pszVal); db_free(&dbv); if (item != NULL) { Menu_ShowItem(hMenuContactRequestAuth, item->subscription == SUB_NONE || item->subscription == SUB_FROM); Menu_ShowItem(hMenuContactGrantAuth, item->subscription == SUB_NONE || item->subscription == SUB_TO); Menu_ShowItem(hMenuContactMUC, item->status != ID_STATUS_OFFLINE); Menu_ShowItem(hMenuContactVoice, item->status != ID_STATUS_OFFLINE && !TlenVoiceIsInUse(this)); Menu_ShowItem(hMenuPicture, item->status != ID_STATUS_OFFLINE); return 0; } } } Menu_ShowItem(hMenuContactMUC, false); Menu_ShowItem(hMenuContactVoice, false); Menu_ShowItem(hMenuContactRequestAuth, false); Menu_ShowItem(hMenuContactGrantAuth, false); return 0; }
int CMPlugin::Load() { InitOptions(); CreateServiceFunction("BuddyExpectator/actionReturned", ContactReturnedAction); CreateServiceFunction("BuddyExpectator/actionStillAbsent", ContactStillAbsentAction); CreateServiceFunction("BuddyExpectator/actionMissYou", MissYouAction); CreateServiceFunction("BuddyExpectator/actionMissYouClick", MenuMissYouClick); HookEvent(ME_DB_CONTACT_SETTINGCHANGED, SettingChanged); HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); HookEvent(ME_SYSTEM_PRESHUTDOWN, onShutdown); HookEvent(ME_DB_CONTACT_ADDED, ContactAdded); // ensure all contacts are timestamped DBVARIANT dbv; DWORD current_time = (DWORD)time(0); for (auto &hContact : Contacts()) { if (!db_get(hContact, MODULENAME, "CreationTime", &dbv)) db_free(&dbv); else db_set_dw(hContact, MODULENAME, "CreationTime", current_time); } g_plugin.registerIcon("BuddyExpectator", iconList); HookEvent(ME_SKIN2_ICONSCHANGED, onIconsChanged); onIconsChanged(0, 0); hExtraIcon = ExtraIcon_RegisterIcolib("buddy_exp", LPGEN("Buddy Expectator"), "enabled_icon"); return 0; }
/* * db_eget -- * Front-end to db_get, special case handling for empty files. * * PUBLIC: int db_eget __P((SCR *, db_recno_t, CHAR_T **, size_t *, int *)); */ int db_eget(SCR *sp, db_recno_t lno, CHAR_T **pp, size_t *lenp, int *isemptyp) /* Line number. */ /* Pointer store. */ /* Length store. */ { db_recno_t l1; if (isemptyp != NULL) *isemptyp = 0; /* If the line exists, simply return it. */ if (!db_get(sp, lno, 0, pp, lenp)) return (0); /* * If the user asked for line 0 or line 1, i.e. the only possible * line in an empty file, find the last line of the file; db_last * fails loudly. */ if ((lno == 0 || lno == 1) && db_last(sp, &l1)) return (1); /* If the file isn't empty, fail loudly. */ if ((lno != 0 && lno != 1) || l1 != 0) { db_err(sp, lno); return (1); } if (isemptyp != NULL) *isemptyp = 1; return (1); }
char const *db_read_string(DB_val *const val, DB_txn *const txn) { assert(txn); assert(val); db_assert(val->size >= 1); char const *const str = val->data; size_t const len = strnlen(str, MIN(val->size, DB_INLINE_MAX)); db_assert('\0' == str[len]); if(0 == len) { db_assert(val->size >= 2); val->data += 2; val->size -= 2; if(0x00 == str[1]) return NULL; if(0x01 == str[1]) return ""; db_assertf(0, "Invalid string type %u\n", str[1]); return NULL; } if(DB_INLINE_TRUNC != len+1) { val->data += len+1; val->size -= len+1; return str; } db_assert(val->size >= len+2); if(0x00 == str[len+1]) { val->data += len+2; val->size -= len+2; return str; } DB_val key = { DB_INLINE_MAX, (char *)str }; DB_val full[1]; int rc = db_get(txn, &key, full); db_assertf(rc >= 0, "Database error %s", db_strerror(rc)); char const *const fstr = full->data; db_assert('\0' == fstr[full->size-1]); return fstr; }
int handle(const int fd, db_t *db, sbuf_t *in, sbuf_t *out) { ssize_t err; ssize_t len; char *key; uint32_t klen; uint32_t vlen; int argc; int arglen; char argv[ARGC_MAX][ARGV_MAX]; if ((err = sbuf_recv(fd, in, &len)) <= 0 && len == 0) { if (err == -1) { fprintf(stdout, "db-server: socket %d recv %s\n", fd, strerror(errno)); } return HANDLE_CLOSE; } arglen = argparse(in->buf, in->len, &argc, argv, ARGC_MAX); if (argc < 1 || arglen == -1) { fprintf(stderr, "db-server: socket %d malformed request\n", fd); return HANDLE_CLOSE; } if (strcmp(argv[0], "set") == 0 && argc >= 5) { key = argv[1]; klen = strlen(key); vlen = atoi(argv[4]); if (vlen + arglen > in->max) { fprintf(stderr, "db-server: socket %d too large value\n", fd); return HANDLE_CLOSE; } if (vlen + arglen > in->len) { return HANDLE_NEEDMOREIN; } if (db_put(db, key, klen, in->buf + arglen, vlen) == DB_OK) { out->len = sprintf(out->buf, "STORED\r\n"); } else { out->len = sprintf(out->buf, "ERROR\r\n"); } } else if (strcmp(argv[0], "get") == 0 && argc >= 2) { key = argv[1]; klen = strlen(key); if ((vlen = db_get(db, key, klen, valbuf, VALBUF_LEN)) != 0) { if (vlen > VALBUF_LEN) return HANDLE_CLOSE; out->len = snprintf(out->buf, out->max, "VALUE %.*s %d %d\r\n%.*s\r\nEND\r\n", klen, key, 0, vlen, vlen, valbuf); } else { out->len = sprintf(out->buf, "END\r\n"); } } else if (strcmp(argv[0], "delete") == 0 && argc >= 2) { key = argv[1]; klen = strlen(key); if ((db_del(db, key, klen)) != 0) { out->len = snprintf(out->buf, out->max, "DELETED\r\n"); } else { out->len = snprintf(out->buf, out->max, "NOT_FOUND\r\n"); } } else { return HANDLE_CLOSE; } if ((err = sbuf_send(fd, out, &len)) <= 0 && len == 0) { if (err == -1) { fprintf(stdout, "db-server: socket %d send %s\n", fd, strerror(errno)); } return HANDLE_CLOSE; } if (out->off < out->len) { return HANDLE_NEEDMOREOUT; } return HANDLE_FINISH; }
void CluiProtocolStatusChanged(int, const char*) { int maxOnline = 0, onlineness = 0; WORD maxStatus = ID_STATUS_OFFLINE; DBVARIANT dbv = { 0 }; int iIcon = 0; HICON hIcon = 0; int rdelta = cfg::dat.bCLeft + cfg::dat.bCRight; BYTE windowStyle; if (pcli->hwndStatus == 0 || cfg::shutDown) return; int protoCount; PROTOACCOUNT **accs; ProtoEnumAccounts(&protoCount, &accs); if (protoCount == 0) return; FreeProtocolData(); g_maxStatus = ID_STATUS_OFFLINE; g_maxProto[0] = 0; int borders[3]; SendMessage(pcli->hwndStatus, SB_GETBORDERS, 0, (LPARAM)&borders); int *partWidths = (int*)_alloca((protoCount + 1)*sizeof(int)); int partCount; if (cfg::dat.bEqualSections) { RECT rc; GetClientRect(pcli->hwndStatus, &rc); rc.right -= borders[0] * 2; int toshow = 0; for (int i = 0; i < protoCount; i++) if (pcli->pfnGetProtocolVisibility(accs[i]->szModuleName)) toshow++; if (toshow > 0) { for (int part = 0, i = 0; i < protoCount; i++) { if (!pcli->pfnGetProtocolVisibility(accs[i]->szModuleName)) continue; partWidths[part] = ((rc.right - rc.left - rdelta) / toshow)*(part + 1) + cfg::dat.bCLeft; if (part == toshow - 1) partWidths[part] += cfg::dat.bCRight; part++; } } partCount = toshow; } else { SIZE textSize; BYTE showOpts = cfg::getByte("CLUI", "SBarShow", 1); TCHAR szName[32]; HDC hdc = GetDC(NULL); HFONT hofont = reinterpret_cast<HFONT>(SelectObject(hdc, (HFONT)SendMessage(pcli->hwndStatus, WM_GETFONT, 0, 0))); // count down since built in ones tend to go at the end partCount = 0; for (int i = 0; i < protoCount; i++) { int idx = pcli->pfnGetAccountIndexByPos(i); if (idx == -1) continue; PROTOACCOUNT *pa = accs[idx]; if (!pcli->pfnGetProtocolVisibility(pa->szModuleName)) continue; int x = 2; if (showOpts & 1) x += 16; if (showOpts & 2) { mir_tstrncpy(szName, pa->tszAccountName, SIZEOF(szName)); szName[SIZEOF(szName) - 1] = 0; if ((showOpts & 4) && mir_tstrlen(szName) < sizeof(szName) - 1) mir_tstrcat(szName, _T(" ")); GetTextExtentPoint32(hdc, szName, (int)mir_tstrlen(szName), &textSize); x += textSize.cx + GetSystemMetrics(SM_CXBORDER) * 4; // The SB panel doesnt allocate enough room } if (showOpts & 4) { TCHAR* modeDescr = pcli->pfnGetStatusModeDescription(CallProtoService(accs[i]->szModuleName, PS_GETSTATUS, 0, 0), 0); GetTextExtentPoint32(hdc, modeDescr, (int)mir_tstrlen(modeDescr), &textSize); x += textSize.cx + GetSystemMetrics(SM_CXBORDER) * 4; // The SB panel doesnt allocate enough room } partWidths[partCount] = (partCount ? partWidths[partCount - 1] : cfg::dat.bCLeft) + x + 2; partCount++; } SelectObject(hdc, hofont); ReleaseDC(NULL, hdc); } if (partCount == 0) { SendMessage(pcli->hwndStatus, SB_SIMPLE, TRUE, 0); return; } SendMessage(pcli->hwndStatus, SB_SIMPLE, FALSE, 0); partWidths[partCount - 1] = -1; windowStyle = cfg::getByte("CLUI", "WindowStyle", 0); SendMessage(pcli->hwndStatus, SB_SETMINHEIGHT, 18 + cfg::dat.bClipBorder + ((windowStyle == SETTING_WINDOWSTYLE_THINBORDER || windowStyle == SETTING_WINDOWSTYLE_NOBORDER) ? 3 : 0), 0); SendMessage(pcli->hwndStatus, SB_SETPARTS, partCount, (LPARAM)partWidths); // count down since built in ones tend to go at the end char *szMaxProto = NULL; for (int i = 0, partCount = 0; i < protoCount; i++) { int idx = pcli->pfnGetAccountIndexByPos(i); if (idx == -1) continue; PROTOACCOUNT *pa = accs[idx]; if (!pcli->pfnGetProtocolVisibility(pa->szModuleName)) continue; int status = CallProtoService(pa->szModuleName, PS_GETSTATUS, 0, 0); ProtocolData *PD = (ProtocolData*)mir_alloc(sizeof(ProtocolData)); PD->RealName = mir_strdup(pa->szModuleName); PD->protopos = partCount; { int flags; flags = SBT_OWNERDRAW; if (cfg::getByte("CLUI", "SBarBevel", 1) == 0) flags |= SBT_NOBORDERS; SendMessageA(pcli->hwndStatus, SB_SETTEXTA, partCount | flags, (LPARAM)PD); } int caps2 = CallProtoService(pa->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0); int caps1 = CallProtoService(pa->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0); if ((caps1 & PF1_IM) && (caps2 & (PF2_LONGAWAY | PF2_SHORTAWAY))) { onlineness = GetStatusOnlineness(status); if (onlineness > maxOnline) { maxStatus = status; maxOnline = onlineness; szMaxProto = pa->szModuleName; } } partCount++; } // update the clui button WORD wStatus = 0; if (!db_get(NULL, "CList", "PrimaryStatus", &dbv)) { if (dbv.type == DBVT_ASCIIZ && mir_strlen(dbv.pszVal) > 1) { wStatus = (WORD)CallProtoService(dbv.pszVal, PS_GETSTATUS, 0, 0); iIcon = IconFromStatusMode(dbv.pszVal, (int)wStatus, 0, &hIcon); } mir_free(dbv.pszVal); } else { wStatus = maxStatus; iIcon = IconFromStatusMode((wStatus >= ID_STATUS_CONNECTING && wStatus < ID_STATUS_OFFLINE) ? szMaxProto : NULL, (int)wStatus, 0, &hIcon); g_maxStatus = (int)wStatus; if (szMaxProto) strncpy_s(g_maxProto, SIZEOF(g_maxProto), szMaxProto, _TRUNCATE); } /* * this is used globally (actually, by the clist control only) to determine if * any protocol is "in connection" state. If true, then the clist discards redraws * and uses timer based sort and redraw handling. This can improve performance * when connecting multiple protocols significantly. */ TCHAR *szStatus = pcli->pfnGetStatusModeDescription(wStatus, 0); /* * set the global status icon and display the global (most online) status mode on the * status mode button */ if (szStatus && pcli->hwndContactList) { HWND hwndClistBtn = GetDlgItem(pcli->hwndContactList, IDC_TBGLOBALSTATUS); if (IsWindow(hwndClistBtn)) { SetWindowText(hwndClistBtn, szStatus); if (!hIcon) SendMessage(hwndClistBtn, BUTTONSETIMLICON, (WPARAM)hCListImages, (LPARAM)iIcon); else SendMessage(hwndClistBtn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); InvalidateRect(hwndClistBtn, NULL, TRUE); } HWND hwndTtbStatus = ClcGetButtonWindow(IDC_TBTOPSTATUS); if (IsWindow(hwndTtbStatus)) { if (g_ButtonItems == NULL) { if (!hIcon) SendMessage(hwndTtbStatus, BUTTONSETIMLICON, (WPARAM)hCListImages, (LPARAM)iIcon); else SendMessage(hwndTtbStatus, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); } InvalidateRect(hwndTtbStatus, NULL, TRUE); } } }
/* * 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); }
/* * 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); }
/* * f_search -- * Do a forward search. * * PUBLIC: int f_search __P((SCR *, * PUBLIC: MARK *, MARK *, CHAR_T *, size_t, CHAR_T **, u_int)); */ int f_search( SCR *sp, MARK *fm, MARK *rm, CHAR_T *ptrn, size_t plen, CHAR_T **eptrn, u_int flags) { busy_t btype; recno_t lno; regmatch_t match[1]; size_t coff, len; int cnt, eval, rval, wrapped; CHAR_T *l; if (search_init(sp, FORWARD, ptrn, plen, eptrn, flags)) return (1); if (LF_ISSET(SEARCH_FILE)) { lno = 1; coff = 0; } else { if (db_get(sp, fm->lno, DBG_FATAL, &l, &len)) return (1); lno = fm->lno; /* * If doing incremental search, start searching at the previous * column, so that we search a minimal distance and still match * special patterns, e.g., \< for beginning of a word. * * Otherwise, start searching immediately after the cursor. If * at the end of the line, start searching on the next line. * This is incompatible (read bug fix) with the historic vi -- * searches for the '$' pattern never moved forward, and the * "-t foo" didn't work if the 'f' was the first character in * the file. */ if (LF_ISSET(SEARCH_INCR)) { if ((coff = fm->cno) != 0) --coff; } else if (fm->cno + 1 >= len) { coff = 0; lno = fm->lno + 1; if (db_get(sp, lno, 0, &l, &len)) { if (!O_ISSET(sp, O_WRAPSCAN)) { if (LF_ISSET(SEARCH_MSG)) search_msg(sp, S_EOF); return (1); } lno = 1; } } else coff = fm->cno + 1; } btype = BUSY_ON; for (cnt = INTERRUPT_CHECK, rval = 1, wrapped = 0;; ++lno, coff = 0) { if (cnt-- == 0) { if (INTERRUPTED(sp)) break; if (LF_ISSET(SEARCH_MSG)) { search_busy(sp, btype); btype = BUSY_UPDATE; } cnt = INTERRUPT_CHECK; } if ((wrapped && lno > fm->lno) || db_get(sp, lno, 0, &l, &len)) { if (wrapped) { if (LF_ISSET(SEARCH_MSG)) search_msg(sp, S_NOTFOUND); break; } if (!O_ISSET(sp, O_WRAPSCAN)) { if (LF_ISSET(SEARCH_MSG)) search_msg(sp, S_EOF); break; } lno = 0; wrapped = 1; continue; } /* If already at EOL, just keep going. */ if (len != 0 && coff == len) continue; /* Set the termination. */ match[0].rm_so = coff; match[0].rm_eo = len; #if defined(DEBUG) && 0 TRACE(sp, "F search: %lu from %u to %u\n", lno, coff, len != 0 ? len - 1 : len); #endif /* Search the line. */ eval = regexec(&sp->re_c, l, 1, match, (match[0].rm_so == 0 ? 0 : REG_NOTBOL) | REG_STARTEND); if (eval == REG_NOMATCH) continue; if (eval != 0) { if (LF_ISSET(SEARCH_MSG)) re_error(sp, eval, &sp->re_c); else (void)sp->gp->scr_bell(sp); break; } /* Warn if the search wrapped. */ if (wrapped && LF_ISSET(SEARCH_WMSG)) search_msg(sp, S_WRAP); #if defined(DEBUG) && 0 TRACE(sp, "F search: %qu to %qu\n", match[0].rm_so, match[0].rm_eo); #endif rm->lno = lno; rm->cno = match[0].rm_so; /* * If a change command, it's possible to move beyond the end * of a line. Historic vi generally got this wrong (e.g. try * "c?$<cr>"). Not all that sure this gets it right, there * are lots of strange cases. */ if (!LF_ISSET(SEARCH_EOL) && rm->cno >= len) rm->cno = len != 0 ? len - 1 : 0; rval = 0; break; } if (LF_ISSET(SEARCH_MSG)) search_busy(sp, BUSY_OFF); return (rval); }
/* ** COMMAND: configuration* ** ** Usage: %vcs configuration METHOD ... ?OPTIONS? ** ** Where METHOD is one of: export import merge pull push reset. All methods ** accept the -R or --repository option to specific a repository. ** ** %vcs configuration export AREA FILENAME ** ** Write to FILENAME exported configuraton information for AREA. ** AREA can be one of: all email project shun skin ticket user ** ** %vcs configuration import FILENAME ** ** Read a configuration from FILENAME, overwriting the current ** configuration. ** ** %vcs configuration merge FILENAME ** ** Read a configuration from FILENAME and merge its values into ** the current configuration. Existing values take priority over ** values read from FILENAME. ** ** %vcs configuration pull AREA ?URL? ** ** Pull and install the configuration from a different server ** identified by URL. If no URL is specified, then the default ** server is used. Use the --legacy option for the older protocol ** (when talking to servers compiled prior to 2011-04-27.) Use ** the --overwrite flag to completely replace local settings with ** content received from URL. ** ** %vcs configuration push AREA ?URL? ** ** Push the local configuration into the remote server identified ** by URL. Admin privilege is required on the remote server for ** this to work. When the same record exists both locally and on ** the remote end, the one that was most recently changed wins. ** Use the --legacy flag when talking to holder servers. ** ** %vcs configuration reset AREA ** ** Restore the configuration to the default. AREA as above. ** ** %vcs configuration sync AREA ?URL? ** ** Synchronize configuration changes in the local repository with ** the remote repository at URL. ** ** Options: ** -R|--repository FILE Extract info from repository FILE ** ** See also: settings, unset */ void configuration_cmd(void) { int n; const char *zMethod; if( g.argc<3 ) { usage("export|import|merge|pull|reset ..."); } db_find_and_open_repository(0, 0); db_open_config(0); zMethod = g.argv[2]; n = strlen(zMethod); if( strncmp(zMethod, "export", n)==0 ) { int mask; const char *zSince = find_option("since",0,1); sqlite3_int64 iStart; if( g.argc!=5 ) { usage("export AREA FILENAME"); } mask = configure_name_to_mask(g.argv[3], 1); if( zSince ) { iStart = db_multi_exec( "SELECT coalesce(strftime('%%s',%Q),strftime('%%s','now',%Q))+0", zSince, zSince ); } else { iStart = 0; } export_config(mask, g.argv[3], iStart, g.argv[4]); } else if( strncmp(zMethod, "import", n)==0 || strncmp(zMethod, "merge", n)==0 ) { Blob in; int groupMask; if( g.argc!=4 ) usage(mprintf("%s FILENAME",zMethod)); blob_read_from_file(&in, g.argv[3]); db_begin_transaction(); if( zMethod[0]=='i' ) { groupMask = CONFIGSET_ALL | CONFIGSET_OVERWRITE; } else { groupMask = CONFIGSET_ALL; } configure_receive_all(&in, groupMask); db_end_transaction(0); } else if( strncmp(zMethod, "pull", n)==0 || strncmp(zMethod, "push", n)==0 || strncmp(zMethod, "sync", n)==0 ) { int mask; const char *zServer; const char *zPw; int legacyFlag = 0; int overwriteFlag = 0; if( zMethod[0]!='s' ) legacyFlag = find_option("legacy",0,0)!=0; if( strncmp(zMethod,"pull",n)==0 ) { overwriteFlag = find_option("overwrite",0,0)!=0; } url_proxy_options(); if( g.argc!=4 && g.argc!=5 ) { usage("pull AREA ?URL?"); } mask = configure_name_to_mask(g.argv[3], 1); if( g.argc==5 ) { zServer = g.argv[4]; zPw = 0; g.dontKeepUrl = 1; } else { zServer = db_get("last-sync-url", 0); if( zServer==0 ) { vcs_fatal("no server specified"); } zPw = unobscure(db_get("last-sync-pw", 0)); } url_parse(zServer); if( g.urlPasswd==0 && zPw ) g.urlPasswd = mprintf("%s", zPw); user_select(); url_enable_proxy("via proxy: "); if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; if( strncmp(zMethod, "push", n)==0 ) { client_sync(0,0,0,0,0,mask); } else if( strncmp(zMethod, "pull", n)==0 ) { client_sync(0,0,0,0,mask,0); } else { client_sync(0,0,0,0,mask,mask); } } else if( strncmp(zMethod, "reset", n)==0 ) { int mask, i; char *zBackup; if( g.argc!=4 ) usage("reset AREA"); mask = configure_name_to_mask(g.argv[3], 1); zBackup = db_text(0, "SELECT strftime('config-backup-%%Y%%m%%d%%H%%M%%f','now')"); db_begin_transaction(); export_config(mask, g.argv[3], 0, zBackup); for(i=0; i<count(aConfig); i++) { const char *zName = aConfig[i].zName; if( (aConfig[i].groupMask & mask)==0 ) continue; if( zName[0]!='@' ) { db_multi_exec("DELETE FROM config WHERE name=%Q", zName); } else if( vcs_strcmp(zName,"@user")==0 ) { db_multi_exec("DELETE FROM user"); db_create_default_users(0, 0); } else if( vcs_strcmp(zName,"@concealed")==0 ) { db_multi_exec("DELETE FROM concealed"); } else if( vcs_strcmp(zName,"@shun")==0 ) { db_multi_exec("DELETE FROM shun"); } else if( vcs_strcmp(zName,"@reportfmt")==0 ) { db_multi_exec("DELETE FROM reportfmt"); } } db_end_transaction(0); vcs_print("Configuration reset to factory defaults.\n"); vcs_print("To recover, use: %s %s import %s\n", vcs_nameofexe(), g.argv[1], zBackup); } else { vcs_fatal("METHOD should be one of:" " export import merge pull push reset"); } }
static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { char text[256]; BOOL bChecked; TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: { DBVARIANT dbv; proto = (TlenProtocol *)lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); TranslateDialogDefault(hwndDlg); if (!db_get_ts(NULL, proto->m_szModuleName, "LoginServer", &dbv)) { SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, dbv.ptszVal); db_free(&dbv); } else SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, _T("tlen.pl")); EnableWindow(GetDlgItem(hwndDlg, IDC_HOST), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_HOSTPORT), TRUE); if (!db_get_ts(NULL, proto->m_szModuleName, "ManualHost", &dbv)) { SetDlgItemText(hwndDlg, IDC_HOST, dbv.ptszVal); db_free(&dbv); } else SetDlgItemText(hwndDlg, IDC_HOST, _T("s1.tlen.pl")); SetDlgItemInt(hwndDlg, IDC_HOSTPORT, db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT), FALSE); CheckDlgButton(hwndDlg, IDC_KEEPALIVE, db_get_b(NULL, proto->m_szModuleName, "KeepAlive", TRUE)); CheckDlgButton(hwndDlg, IDC_USE_SSL, db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE)); CheckDlgButton(hwndDlg, IDC_VISIBILITY_SUPPORT, db_get_b(NULL, proto->m_szModuleName, "VisibilitySupport", FALSE)); // File transfer options bChecked = FALSE; if (db_get_b(NULL, proto->m_szModuleName, "UseFileProxy", FALSE) == TRUE) { bChecked = TRUE; CheckDlgButton(hwndDlg, IDC_FILE_USE_PROXY, TRUE); } EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); if (db_get_b(NULL, proto->m_szModuleName, "FileProxyAuth", FALSE) == TRUE) CheckDlgButton(hwndDlg, IDC_FILE_PROXY_USE_AUTH, TRUE); else bChecked = FALSE; EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("Forwarding")); SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("SOCKS4")); SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("SOCKS5")); SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_SETCURSEL, db_get_w(NULL, proto->m_szModuleName, "FileProxyType", 0), 0); if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyHost", &dbv)) { SetDlgItemText(hwndDlg, IDC_FILE_PROXY_HOST, dbv.ptszVal); db_free(&dbv); } SetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, db_get_w(NULL, proto->m_szModuleName, "FileProxyPort", 0), FALSE); if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyUsername", &dbv)) { SetDlgItemText(hwndDlg, IDC_FILE_PROXY_USER, dbv.ptszVal); db_free(&dbv); } if (!db_get_s(NULL, proto->m_szModuleName, "FileProxyPassword", &dbv)) { SetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, dbv.pszVal); db_free(&dbv); } return TRUE; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_FILE_PROXY_TYPE: if (HIWORD(wParam) == CBN_SELCHANGE) MarkChanges(4, hwndDlg); break; case IDC_EDIT_LOGIN_SERVER: case IDC_HOST: case IDC_HOSTPORT: case IDC_FILE_PROXY_HOST: case IDC_FILE_PROXY_PORT: case IDC_FILE_PROXY_USER: case IDC_FILE_PROXY_PASSWORD: if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) MarkChanges(4, hwndDlg); break; case IDC_FILE_USE_PROXY: bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); case IDC_FILE_PROXY_USE_AUTH: bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH) & IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); MarkChanges(4, hwndDlg); break; case IDC_KEEPALIVE: case IDC_VISIBILITY_SUPPORT: case IDC_USE_SSL: MarkChanges(4, hwndDlg); break; } } break; case WM_NOTIFY: switch (((LPNMHDR) lParam)->code) { case PSN_APPLY: WORD port; BOOL useEncryption; BOOL reconnectRequired = FALSE; DBVARIANT dbv; GetDlgItemTextA(hwndDlg, IDC_EDIT_LOGIN_SERVER, text, sizeof(text)); if (db_get(NULL, proto->m_szModuleName, "LoginServer", &dbv) || strcmp(text, dbv.pszVal)) reconnectRequired = TRUE; if (dbv.pszVal != NULL) db_free(&dbv); db_set_s(NULL, proto->m_szModuleName, "LoginServer", strlwr(text)); GetDlgItemTextA(hwndDlg, IDC_HOST, text, sizeof(text)); if (db_get(NULL, proto->m_szModuleName, "ManualHost", &dbv) || strcmp(text, dbv.pszVal)) reconnectRequired = TRUE; if (dbv.pszVal != NULL) db_free(&dbv); db_set_s(NULL, proto->m_szModuleName, "ManualHost", text); port = (WORD) GetDlgItemInt(hwndDlg, IDC_HOSTPORT, NULL, FALSE); if (db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT) != port) reconnectRequired = TRUE; db_set_w(NULL, proto->m_szModuleName, "ManualPort", port); proto->tlenOptions.sendKeepAlive = IsDlgButtonChecked(hwndDlg, IDC_KEEPALIVE); db_set_b(NULL, proto->m_szModuleName, "KeepAlive", (BYTE) proto->tlenOptions.sendKeepAlive); useEncryption = IsDlgButtonChecked(hwndDlg, IDC_USE_SSL); if (db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE) != useEncryption) reconnectRequired = TRUE; db_set_b(NULL, proto->m_szModuleName, "UseEncryption", (BYTE) useEncryption); db_set_b(NULL, proto->m_szModuleName, "VisibilitySupport", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VISIBILITY_SUPPORT)); // File transfer options db_set_b(NULL, proto->m_szModuleName, "UseFileProxy", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY)); db_set_w(NULL, proto->m_szModuleName, "FileProxyType", (WORD) SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_GETCURSEL, 0, 0)); GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_HOST, text, sizeof(text)); db_set_s(NULL, proto->m_szModuleName, "FileProxyHost", text); db_set_w(NULL, proto->m_szModuleName, "FileProxyPort", (WORD) GetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, NULL, FALSE)); db_set_b(NULL, proto->m_szModuleName, "FileProxyAuth", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH)); GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_USER, text, sizeof(text)); db_set_s(NULL, proto->m_szModuleName, "FileProxyUsername", text); GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, text, sizeof(text)); db_set_s(NULL, proto->m_szModuleName, "FileProxyPassword", text); if (reconnectRequired && proto->isConnected) MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); ApplyChanges(proto, 4); return TRUE; } break; } return FALSE; }
static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { char text[256]; TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: { DBVARIANT dbv; proto = (TlenProtocol *)lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); TranslateDialogDefault(hwndDlg); if (!db_get_ts(NULL, proto->m_szModuleName, "LoginName", &dbv)) { SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal); db_free(&dbv); } if (!db_get(NULL, proto->m_szModuleName, "Password", &dbv)) { SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal); db_free(&dbv); } CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE)); CheckDlgButton(hwndDlg, IDC_RECONNECT, proto->tlenOptions.reconnect); CheckDlgButton(hwndDlg, IDC_ROSTER_SYNC, proto->tlenOptions.rosterSync); CheckDlgButton(hwndDlg, IDC_SHOW_OFFLINE, proto->tlenOptions.offlineAsInvisible); CheckDlgButton(hwndDlg, IDC_OFFLINE_MESSAGE, proto->tlenOptions.leaveOfflineMessage); CheckDlgButton(hwndDlg, IDC_IGNORE_ADVERTISEMENTS, proto->tlenOptions.ignoreAdvertisements); CheckDlgButton(hwndDlg, IDC_AVATARS, proto->tlenOptions.enableAvatars); CheckDlgButton(hwndDlg, IDC_VERSIONINFO, proto->tlenOptions.enableVersion); CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, proto->tlenOptions.useNudge); CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, proto->tlenOptions.logAlerts); SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all alerts")); SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore alerts from unauthorized contacts")); SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all alerts")); SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_SETCURSEL, proto->tlenOptions.alertPolicy, 0); SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me")); SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts")); SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations")); SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts")); SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation")); SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_SETCURSEL, proto->tlenOptions.groupChatPolicy, 0); SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all images")); SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore images from unauthorized contacts")); SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all images")); SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_SETCURSEL, proto->tlenOptions.imagePolicy, 0); SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("<Last message>")); SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_ONLINE, 0)); SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_AWAY, 0)); SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_NA, 0)); SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_DND, 0)); SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_FREECHAT, 0)); SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_INVISIBLE, 0)); SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_SETCURSEL, proto->tlenOptions.offlineMessageOption, 0); mir_subclassWindow(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), TlenValidateUsernameWndProc); return TRUE; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_EDIT_USERNAME: case IDC_EDIT_PASSWORD: if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); break; // Fall through case IDC_SAVEPASSWORD: case IDC_RECONNECT: case IDC_ROSTER_SYNC: case IDC_IGNORE_ADVERTISEMENTS: case IDC_SHOW_OFFLINE: case IDC_OFFLINE_MESSAGE: MarkChanges(1, hwndDlg); break; case IDC_LOG_ALERTS: CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, BST_UNCHECKED); MarkChanges(1, hwndDlg); break; case IDC_NUDGE_SUPPORT: CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, BST_UNCHECKED); MarkChanges(1, hwndDlg); break; case IDC_REGISTERACCOUNT: CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER); break; case IDC_OFFLINE_MESSAGE_OPTION: case IDC_ALERT_POLICY: case IDC_MUC_POLICY: if (HIWORD(wParam) == CBN_SELCHANGE) MarkChanges(1, hwndDlg); break; default: MarkChanges(1, hwndDlg); break; } break; case WM_NOTIFY: switch (((LPNMHDR) lParam)->code) { case PSN_APPLY: { BOOL reconnectRequired = FALSE; DBVARIANT dbv; GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text)); if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv) || strcmp(text, dbv.pszVal)) reconnectRequired = TRUE; if (dbv.pszVal != NULL) db_free(&dbv); db_set_s(NULL, proto->m_szModuleName, "LoginName", strlwr(text)); if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) { GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text)); if (db_get(NULL, proto->m_szModuleName, "Password", &dbv) || strcmp(text, dbv.pszVal)) reconnectRequired = TRUE; if (dbv.pszVal != NULL) db_free(&dbv); db_set_s(NULL, proto->m_szModuleName, "Password", text); } else db_unset(NULL, proto->m_szModuleName, "Password"); db_set_b(NULL, proto->m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)); db_set_b(NULL, proto->m_szModuleName, "Reconnect", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_RECONNECT)); db_set_b(NULL, proto->m_szModuleName, "RosterSync", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ROSTER_SYNC)); db_set_b(NULL, proto->m_szModuleName, "OfflineAsInvisible", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOW_OFFLINE)); db_set_b(NULL, proto->m_szModuleName, "IgnoreAdvertisements", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IGNORE_ADVERTISEMENTS)); db_set_b(NULL, proto->m_szModuleName, "LeaveOfflineMessage", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_OFFLINE_MESSAGE)); db_set_w(NULL, proto->m_szModuleName, "OfflineMessageOption", (WORD) SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_GETCURSEL, 0, 0)); db_set_w(NULL, proto->m_szModuleName, "AlertPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_GETCURSEL, 0, 0)); db_set_w(NULL, proto->m_szModuleName, "GroupChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_GETCURSEL, 0, 0)); db_set_w(NULL, proto->m_szModuleName, "ImagePolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_GETCURSEL, 0, 0)); db_set_b(NULL, proto->m_szModuleName, "EnableAvatars", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AVATARS)); db_set_b(NULL, proto->m_szModuleName, "EnableVersion", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VERSIONINFO)); db_set_b(NULL, proto->m_szModuleName, "UseNudge", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_NUDGE_SUPPORT)); db_set_b(NULL, proto->m_szModuleName, "LogAlerts", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LOG_ALERTS)); if (reconnectRequired && proto->isConnected) MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); ApplyChanges(proto, 1); return TRUE; } } break; } return FALSE; }
void loadServerInfoNexuizServerInfoDialog(entity me, float i, entity slist) { float m; string s, typestr, versionstr, rmversion, numh, maxp; var ip = gethostcachestring(SLIST_FIELD_CNAME, i); SLIST_FIELD_CNAME = gethostcacheindexforkey("cname"); me.currentServerCName = strzone(ip); me.cnameLabel.setText(me.cnameLabel, me.currentServerCName); SLIST_FIELD_NAME = gethostcacheindexforkey("name"); var clrname = db_get(slist.alt_hostnames_db, ip); if(clrname == "") { me.currentServerName = strzone(gethostcachestring(SLIST_FIELD_NAME, i)); me.nameLabel.allowColors = FALSE; } else { me.currentServerName = strzone(clrname); me.nameLabel.allowColors = TRUE; } me.nameLabel.setText(me.nameLabel, me.currentServerName); SLIST_FIELD_QCSTATUS = gethostcacheindexforkey("qcstatus"); s = gethostcachestring(SLIST_FIELD_QCSTATUS, i); m = tokenizebyseparator(s, ":"); if(m > 1) { typestr = argv (0); versionstr = argv(1); } else { typestr = "N/A"; versionstr = "N/A"; } m = tokenizebyseparator(versionstr, "_rm-"); rmversion = argv(1); me.currentServerType = gametype_Name_to_LongName(typestr); //strzone(typestr); me.typeLabel.setText(me.typeLabel, me.currentServerType); SLIST_FIELD_MAP = gethostcacheindexforkey("map"); me.currentServerMap = strzone(gethostcachestring(SLIST_FIELD_MAP, i)); me.mapLabel.setText(me.mapLabel, me.currentServerMap); SLIST_FIELD_PLAYERS = gethostcacheindexforkey("players"); me.currentServerPlayers = strzone(gethostcachestring(SLIST_FIELD_PLAYERS, i)); me.rawPlayerList.setPlayerList(me.rawPlayerList, me.currentServerPlayers); SLIST_FIELD_NUMHUMANS = gethostcacheindexforkey("numhumans"); numh = ftos(gethostcachenumber(SLIST_FIELD_NUMHUMANS, i)); SLIST_FIELD_MAXPLAYERS = gethostcacheindexforkey("maxplayers"); maxp = ftos(gethostcachenumber(SLIST_FIELD_MAXPLAYERS, i)); me.currentServerNumPlayers = strzone(strcat(numh,"/",maxp)); me.numPlayersLabel.setText(me.numPlayersLabel, me.currentServerNumPlayers); SLIST_FIELD_NUMBOTS = gethostcacheindexforkey("numbots"); s = ftos(gethostcachenumber(SLIST_FIELD_NUMBOTS, i)); me.currentServerNumBots = strzone(s); me.numBotsLabel.setText(me.numBotsLabel, me.currentServerNumBots); SLIST_FIELD_MOD = gethostcacheindexforkey("mod"); me.currentServerMod = strzone(gethostcachestring(SLIST_FIELD_MOD, i)); me.modLabel.setText(me.modLabel, me.currentServerMod); me.currentServerVersion = strzone(versionstr); me.versionLabel.setText(me.versionLabel, me.currentServerVersion); me.currentServerRMLabel = strzone(if(rmversion && rmversion != "") strcat("This server is running RocketMinsta ", rmversion) else strcat("This server is running Nexuiz ", versionstr)); me.rmLabel.setText(me.rmLabel, me.currentServerRMLabel); SLIST_FIELD_PING = gethostcacheindexforkey("ping"); s = ftos(gethostcachenumber(SLIST_FIELD_PING, i)); me.currentServerPing = strzone(s); me.pingLabel.setText(me.pingLabel, me.currentServerPing); }
/* * v_change -- [buffer][count]c[count]motion * [buffer][count]C * [buffer][count]S * Change command. * * PUBLIC: int v_change __P((SCR *, VICMD *)); */ int v_change(SCR *sp, VICMD *vp) { size_t blen, len; u_int32_t flags; int isempty, lmode, rval; CHAR_T *bp; CHAR_T *p; /* * 'c' can be combined with motion commands that set the resulting * cursor position, i.e. "cG". Clear the VM_RCM flags and make the * resulting cursor position stick, inserting text has its own rules * for cursor positioning. */ F_CLR(vp, VM_RCM_MASK); F_SET(vp, VM_RCM_SET); /* * Find out if the file is empty, it's easier to handle it as a * special case. */ if (vp->m_start.lno == vp->m_stop.lno && db_eget(sp, vp->m_start.lno, &p, &len, &isempty)) { if (!isempty) return (1); return (v_ia(sp, vp)); } flags = set_txt_std(sp, vp, 0); sp->showmode = SM_CHANGE; /* * Move the cursor to the start of the change. Note, if autoindent * is turned on, the cc command in line mode changes from the first * *non-blank* character of the line, not the first character. And, * to make it just a bit more exciting, the initial space is handled * as auto-indent characters. */ lmode = F_ISSET(vp, VM_LMODE) ? CUT_LINEMODE : 0; if (lmode) { vp->m_start.cno = 0; if (O_ISSET(sp, O_AUTOINDENT)) { if (nonblank(sp, vp->m_start.lno, &vp->m_start.cno)) return (1); LF_SET(TXT_AICHARS); } } sp->lno = vp->m_start.lno; sp->cno = vp->m_start.cno; LOG_CORRECT; /* * If not in line mode and changing within a single line, copy the * text and overwrite it. */ if (!lmode && vp->m_start.lno == vp->m_stop.lno) { /* * !!! * Historic practice, c did not cut into the numeric buffers, * only the unnamed one. */ if (cut(sp, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL, &vp->m_start, &vp->m_stop, lmode)) return (1); if (len == 0) LF_SET(TXT_APPENDEOL); LF_SET(TXT_EMARK | TXT_OVERWRITE); return (v_txt(sp, vp, &vp->m_stop, p, len, 0, OOBLNO, F_ISSET(vp, VC_C1SET) ? vp->count : 1, flags)); } /* * It's trickier if in line mode or changing over multiple lines. If * we're in line mode delete all of the lines and insert a replacement * line which the user edits. If there was leading whitespace in the * first line being changed, we copy it and use it as the replacement. * If we're not in line mode, we delete the text and start inserting. * * !!! * Copy the text. Historic practice, c did not cut into the numeric * buffers, only the unnamed one. */ if (cut(sp, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL, &vp->m_start, &vp->m_stop, lmode)) return (1); /* If replacing entire lines and there's leading text. */ if (lmode && vp->m_start.cno) { /* * Get a copy of the first line changed, and copy out the * leading text. */ if (db_get(sp, vp->m_start.lno, DBG_FATAL, &p, &len)) return (1); GET_SPACE_RETW(sp, bp, blen, vp->m_start.cno); MEMMOVEW(bp, p, vp->m_start.cno); } else bp = NULL; /* Delete the text. */ if (del(sp, &vp->m_start, &vp->m_stop, lmode)) return (1); /* If replacing entire lines, insert a replacement line. */ if (lmode) { if (db_insert(sp, vp->m_start.lno, bp, vp->m_start.cno)) return (1); sp->lno = vp->m_start.lno; len = sp->cno = vp->m_start.cno; } /* Get the line we're editing. */ if (db_eget(sp, vp->m_start.lno, &p, &len, &isempty)) { if (!isempty) return (1); len = 0; } /* Check to see if we're appending to the line. */ if (vp->m_start.cno >= len) LF_SET(TXT_APPENDEOL); rval = v_txt(sp, vp, NULL, p, len, 0, OOBLNO, F_ISSET(vp, VC_C1SET) ? vp->count : 1, flags); if (bp != NULL) FREE_SPACEW(sp, bp, blen); return (rval); }
/* * v_sectionb -- [count][[ * Move backward count sections/functions. * * PUBLIC: int v_sectionb(SCR *, VICMD *); */ int v_sectionb(SCR *sp, VICMD *vp) { size_t len; recno_t cnt, lno; CHAR_T *p; char *list, *lp; /* An empty file or starting from line 1 is always illegal. */ if (vp->m_start.lno <= 1) { v_sof(sp, NULL); return (1); } /* Get the macro list. */ if ((list = O_STR(sp, O_SECTIONS)) == NULL) return (1); cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; for (lno = vp->m_start.lno; !db_get(sp, --lno, 0, &p, &len);) { if (len == 0) continue; if (p[0] == '{') { if (!--cnt) goto adjust1; continue; } /* * !!! * Historic documentation (USD:15-11, 4.2) said that formfeed * characters (^L) in the first column delimited sections. * The historic code mentions formfeed characters, but never * implements them. Seems reasonable, do it. */ if (p[0] == '\014') { if (!--cnt) goto adjust1; continue; } if (p[0] != '.' || len < 2) continue; for (lp = list; *lp != '\0'; lp += 2 * sizeof(*lp)) if (lp[0] == p[1] && ((lp[1] == ' ' && len == 2) || lp[1] == p[2]) && !--cnt) { adjust1: vp->m_stop.lno = lno; vp->m_stop.cno = 0; goto ret1; } } /* * If moving backward, reached SOF, which is a movement sink. * We already checked for starting there. */ vp->m_stop.lno = 1; vp->m_stop.cno = 0; /* * All commands move to the end of the range. * * !!! * Historic practice is the section cut was in line mode if it started * from column 0 and was in the backward direction. Otherwise, left * motion commands adjust the starting point to the character before * the current one. What makes this worse is that if it cut to line * mode it also went to the first non-<blank>. */ ret1: if (vp->m_start.cno == 0) { F_CLR(vp, VM_RCM_MASK); F_SET(vp, VM_RCM_SETFNB); --vp->m_start.lno; F_SET(vp, VM_LMODE); } else --vp->m_start.cno; vp->m_final = vp->m_stop; return (0); }
/* * b_search -- * Do a backward search. * * PUBLIC: int b_search __P((SCR *, * PUBLIC: MARK *, MARK *, CHAR_T *, size_t, CHAR_T **, u_int)); */ int b_search( SCR *sp, MARK *fm, MARK *rm, CHAR_T *ptrn, size_t plen, CHAR_T **eptrn, u_int flags) { busy_t btype; recno_t lno; regmatch_t match[1]; size_t coff, last, len; int cnt, eval, rval, wrapped; CHAR_T *l; if (search_init(sp, BACKWARD, ptrn, plen, eptrn, flags)) return (1); /* * If doing incremental search, set the "starting" position past the * current column, so that we search a minimal distance and still * match special patterns, e.g., \> for the end of a word. This is * safe when the cursor is at the end of a line because we only use * it for comparison with the location of the match. * * Otherwise, start searching immediately before the cursor. If in * the first column, start search on the previous line. */ if (LF_ISSET(SEARCH_INCR)) { lno = fm->lno; coff = fm->cno + 1; } else { if (fm->cno == 0) { if (fm->lno == 1 && !O_ISSET(sp, O_WRAPSCAN)) { if (LF_ISSET(SEARCH_MSG)) search_msg(sp, S_SOF); return (1); } lno = fm->lno - 1; } else lno = fm->lno; coff = fm->cno; } btype = BUSY_ON; for (cnt = INTERRUPT_CHECK, rval = 1, wrapped = 0;; --lno, coff = 0) { if (cnt-- == 0) { if (INTERRUPTED(sp)) break; if (LF_ISSET(SEARCH_MSG)) { search_busy(sp, btype); btype = BUSY_UPDATE; } cnt = INTERRUPT_CHECK; } if ((wrapped && lno < fm->lno) || lno == 0) { if (wrapped) { if (LF_ISSET(SEARCH_MSG)) search_msg(sp, S_NOTFOUND); break; } if (!O_ISSET(sp, O_WRAPSCAN)) { if (LF_ISSET(SEARCH_MSG)) search_msg(sp, S_SOF); break; } if (db_last(sp, &lno)) break; if (lno == 0) { if (LF_ISSET(SEARCH_MSG)) search_msg(sp, S_EMPTY); break; } ++lno; wrapped = 1; continue; } if (db_get(sp, lno, 0, &l, &len)) break; /* Set the termination. */ match[0].rm_so = 0; match[0].rm_eo = len; #if defined(DEBUG) && 0 TRACE(sp, "B search: %lu from 0 to %qu\n", lno, match[0].rm_eo); #endif /* Search the line. */ eval = regexec(&sp->re_c, l, 1, match, (match[0].rm_eo == len ? 0 : REG_NOTEOL) | REG_STARTEND); if (eval == REG_NOMATCH) continue; if (eval != 0) { if (LF_ISSET(SEARCH_MSG)) re_error(sp, eval, &sp->re_c); else (void)sp->gp->scr_bell(sp); break; } /* Check for a match starting past the cursor. */ if (coff != 0 && match[0].rm_so >= coff) continue; /* Warn if the search wrapped. */ if (wrapped && LF_ISSET(SEARCH_WMSG)) search_msg(sp, S_WRAP); #if defined(DEBUG) && 0 TRACE(sp, "B found: %qu to %qu\n", match[0].rm_so, match[0].rm_eo); #endif /* * We now have the first match on the line. Step through the * line character by character until find the last acceptable * match. This is painful, we need a better interface to regex * to make this work. */ for (;;) { last = match[0].rm_so++; if (match[0].rm_so >= len) break; match[0].rm_eo = len; eval = regexec(&sp->re_c, l, 1, match, (match[0].rm_so == 0 ? 0 : REG_NOTBOL) | REG_STARTEND); if (eval == REG_NOMATCH) break; if (eval != 0) { if (LF_ISSET(SEARCH_MSG)) re_error(sp, eval, &sp->re_c); else (void)sp->gp->scr_bell(sp); goto err; } if (coff && match[0].rm_so >= coff) break; } rm->lno = lno; /* See comment in f_search(). */ if (!LF_ISSET(SEARCH_EOL) && last >= len) rm->cno = len != 0 ? len - 1 : 0; else rm->cno = last; rval = 0; break; } err: if (LF_ISSET(SEARCH_MSG)) search_busy(sp, BUSY_OFF); return (rval); }
/* * v_sectionf -- [count]]] * Move forward count sections/functions. * * !!! * Using ]] as a motion command was a bit special, historically. It could * match } as well as the usual { and section values. If it matched a { or * a section, it did NOT include the matched line. If it matched a }, it * did include the line. No clue why. * * PUBLIC: int v_sectionf(SCR *, VICMD *); */ int v_sectionf(SCR *sp, VICMD *vp) { recno_t cnt, lno; size_t len; CHAR_T *p; char *list, *lp; /* Get the macro list. */ if ((list = O_STR(sp, O_SECTIONS)) == NULL) return (1); /* * !!! * If the starting cursor position is at or before any non-blank * characters in the line, i.e. the movement is cutting all of the * line's text, the buffer is in line mode. It's a lot easier to * check here, because we know that the end is going to be the start * or end of a line. */ if (ISMOTION(vp)) if (vp->m_start.cno == 0) F_SET(vp, VM_LMODE); else { vp->m_stop = vp->m_start; vp->m_stop.cno = 0; if (nonblank(sp, vp->m_stop.lno, &vp->m_stop.cno)) return (1); if (vp->m_start.cno <= vp->m_stop.cno) F_SET(vp, VM_LMODE); } cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; for (lno = vp->m_start.lno; !db_get(sp, ++lno, 0, &p, &len);) { if (len == 0) continue; if (p[0] == '{' || (ISMOTION(vp) && p[0] == '}')) { if (!--cnt) { if (p[0] == '{') goto adjust1; goto adjust2; } continue; } /* * !!! * Historic documentation (USD:15-11, 4.2) said that formfeed * characters (^L) in the first column delimited sections. * The historic code mentions formfeed characters, but never * implements them. Seems reasonable, do it. */ if (p[0] == '\014') { if (!--cnt) goto adjust1; continue; } if (p[0] != '.' || len < 2) continue; for (lp = list; *lp != '\0'; lp += 2 * sizeof(*lp)) if (lp[0] == p[1] && ((lp[1] == ' ' && len == 2) || lp[1] == p[2]) && !--cnt) { /* * !!! * If not cutting this line, adjust to the end * of the previous one. Otherwise, position to * column 0. */ adjust1: if (ISMOTION(vp)) goto ret1; adjust2: vp->m_stop.lno = lno; vp->m_stop.cno = 0; goto ret2; } } /* If moving forward, reached EOF, check to see if we started there. */ if (vp->m_start.lno == lno - 1) { v_eof(sp, NULL); return (1); } ret1: if (db_get(sp, --lno, DBG_FATAL, NULL, &len)) return (1); vp->m_stop.lno = lno; vp->m_stop.cno = len ? len - 1 : 0; /* * Non-motion commands go to the end of the range. Delete and * yank stay at the start of the range. Ignore others. */ ret2: if (ISMOTION(vp)) { vp->m_final = vp->m_start; if (F_ISSET(vp, VM_LMODE)) vp->m_final.cno = 0; } else vp->m_final = vp->m_stop; return (0); }
/* * 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); }
void TlenIqResultRoster(TlenProtocol *proto, XmlNode *iqNode) { XmlNode *queryNode; char *type; char *str; // RECVED: roster information // ACTION: populate LIST_ROSTER and create contact for any new rosters if ((type=TlenXmlGetAttrValue(iqNode, "type")) == NULL) return; if ((queryNode=TlenXmlGetChild(iqNode, "query")) == NULL) return; if (!strcmp(type, "result")) { str = TlenXmlGetAttrValue(queryNode, "xmlns"); if (str != NULL && !strcmp(str, "jabber:iq:roster")) { DBVARIANT dbv; XmlNode *itemNode, *groupNode; TLEN_SUBSCRIPTION sub; TLEN_LIST_ITEM *item; char *jid, *name, *nick; int i, oldStatus; for (i=0; i<queryNode->numChild; i++) { itemNode = queryNode->child[i]; if (!strcmp(itemNode->name, "item")) { str = TlenXmlGetAttrValue(itemNode, "subscription"); if (str == NULL) sub = SUB_NONE; else if (!strcmp(str, "both")) sub = SUB_BOTH; else if (!strcmp(str, "to")) sub = SUB_TO; else if (!strcmp(str, "from")) sub = SUB_FROM; else sub = SUB_NONE; //if (str != NULL && (!strcmp(str, "to") || !strcmp(str, "both"))) { if ((jid=TlenXmlGetAttrValue(itemNode, "jid")) != NULL) { if ((name=TlenXmlGetAttrValue(itemNode, "name")) != NULL) nick = TlenTextDecode(name); else nick = TlenLocalNickFromJID(jid); if (nick != NULL) { MCONTACT hContact; item = TlenListAdd(proto, LIST_ROSTER, jid); if (item->nick) mir_free(item->nick); item->nick = nick; item->subscription = sub; if ((hContact=TlenHContactFromJID(proto, jid)) == NULL) { // Received roster has a new JID. // Add the jid (with empty resource) to Miranda contact list. hContact = TlenDBCreateContact(proto, jid, nick, FALSE); } db_set_s(hContact, "CList", "MyHandle", nick); if (item->group) mir_free(item->group); if ((groupNode=TlenXmlGetChild(itemNode, "group")) != NULL && groupNode->text != NULL) { item->group = TlenGroupDecode(groupNode->text); Clist_CreateGroup(0, _A2T(item->group)); // Don't set group again if already correct, or Miranda may show wrong group count in some case if (!db_get(hContact, "CList", "Group", &dbv)) { if (strcmp(dbv.pszVal, item->group)) db_set_s(hContact, "CList", "Group", item->group); db_free(&dbv); } else db_set_s(hContact, "CList", "Group", item->group); } else { item->group = NULL; db_unset(hContact, "CList", "Group"); } if (!db_get(hContact, proto->m_szModuleName, "AvatarHash", &dbv)) { if (item->avatarHash) mir_free(item->avatarHash); item->avatarHash = mir_strdup(dbv.pszVal); proto->debugLogA("Setting hash [%s] = %s", nick, item->avatarHash); db_free(&dbv); } item->avatarFormat = db_get_dw(hContact, proto->m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN); } } } } // Delete orphaned contacts (if roster sync is enabled) if (db_get_b(NULL, proto->m_szModuleName, "RosterSync", FALSE) == TRUE) { for (MCONTACT hContact = db_find_first(proto->m_szModuleName); hContact; ) { MCONTACT hNext = hContact = db_find_next(hContact, proto->m_szModuleName); ptrA jid( db_get_sa(hContact, proto->m_szModuleName, "jid")); if (jid != NULL) { if (!TlenListExist(proto, LIST_ROSTER, jid)) { proto->debugLogA("Syncing roster: deleting 0x%x", hContact); CallService(MS_DB_CONTACT_DELETE, hContact, 0); } } hContact = hNext; } } CLISTMENUITEM mi = { sizeof(mi) }; mi.flags = CMIM_FLAGS; Menu_ModifyItem(proto->hMenuMUC, &mi); if (proto->hMenuChats != NULL) Menu_ModifyItem(proto->hMenuChats, &mi); proto->isOnline = TRUE; proto->debugLogA("Status changed via THREADSTART"); oldStatus = proto->m_iStatus; TlenSendPresence(proto, proto->m_iDesiredStatus); ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->m_iStatus); } } }
void db_get_b(database *db, const dstr doc_name, db_get_bcb callback) { db_get(db, doc_name, (void *)Block_copy(callback), _get_bcb); }
// Tlen actually use jabber:iq:search for other users vCard or jabber:iq:register for own vCard void TlenIqResultVcard(TlenProtocol *proto, XmlNode *iqNode) { XmlNode *queryNode, *itemNode, *n; char *type, *jid; char text[128]; MCONTACT hContact; char *nText; // TlenLog("<iq/> iqIdGetVcard (tlen)"); if ((type=TlenXmlGetAttrValue(iqNode, "type")) == NULL) return; if (!strcmp(type, "result")) { BOOL hasFirst, hasLast, hasNick, hasEmail, hasCity, hasAge, hasGender, hasSchool, hasLookFor, hasOccupation; DBVARIANT dbv; int i; if ((queryNode=TlenXmlGetChild(iqNode, "query")) == NULL) return; if ((itemNode=TlenXmlGetChild(queryNode, "item")) == NULL) return; if ((jid=TlenXmlGetAttrValue(itemNode, "jid")) != NULL) { if (db_get(NULL, proto->m_szModuleName, "LoginServer", &dbv)) return; if (strchr(jid, '@') != NULL) { mir_snprintf(text, SIZEOF(text), "%s", jid); } else { mir_snprintf(text, SIZEOF(text), "%s@%s", jid, dbv.pszVal); // Add @tlen.pl } db_free(&dbv); if ((hContact=TlenHContactFromJID(proto, text)) == NULL) { if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv)) return; if (strcmp(dbv.pszVal, jid)) { db_free(&dbv); return; } db_free(&dbv); } } else { hContact = NULL; } hasFirst = hasLast = hasNick = hasEmail = hasCity = hasAge = hasGender = hasOccupation = hasLookFor = hasSchool = FALSE; for (i=0; i<itemNode->numChild; i++) { n = itemNode->child[i]; if (n == NULL || n->name == NULL) continue; if (!strcmp(n->name, "first")) { if (n->text != NULL) { hasFirst = TRUE; nText = TlenTextDecode(n->text); db_set_s(hContact, proto->m_szModuleName, "FirstName", nText); mir_free(nText); } } else if (!strcmp(n->name, "last")) { if (n->text != NULL) { hasLast = TRUE; nText = TlenTextDecode(n->text); db_set_s(hContact, proto->m_szModuleName, "LastName", nText); mir_free(nText); } } else if (!strcmp(n->name, "nick")) { if (n->text != NULL) { hasNick = TRUE; nText = TlenTextDecode(n->text); db_set_s(hContact, proto->m_szModuleName, "Nick", nText); mir_free(nText); } } else if (!strcmp(n->name, "email")) { if (n->text != NULL) { hasEmail = TRUE; nText = TlenTextDecode(n->text); db_set_s(hContact, proto->m_szModuleName, "e-mail", nText); mir_free(nText); } } else if (!strcmp(n->name, "c")) { if (n->text != NULL) { hasCity = TRUE; nText = TlenTextDecode(n->text); db_set_s(hContact, proto->m_szModuleName, "City", nText); mir_free(nText); } } else if (!strcmp(n->name, "b")) { if (n->text != NULL) { WORD nAge; hasAge = TRUE; nAge = atoi(n->text); db_set_w(hContact, proto->m_szModuleName, "Age", nAge); } } else if (!strcmp(n->name, "s")) { if (n->text != NULL && n->text[1] == '\0' && (n->text[0] == '1' || n->text[0] == '2')) { hasGender = TRUE; db_set_b(hContact, proto->m_szModuleName, "Gender", (BYTE) (n->text[0] == '1'?'M':'F')); } } else if (!strcmp(n->name, "e")) { if (n->text != NULL) { hasSchool = TRUE; nText = TlenTextDecode(n->text); db_set_s(hContact, proto->m_szModuleName, "School", nText); mir_free(nText); } } else if (!strcmp(n->name, "j")) { if (n->text != NULL) { WORD nOccupation; hasOccupation = TRUE; nOccupation = atoi(n->text); db_set_w(hContact, proto->m_szModuleName, "Occupation", nOccupation); } } else if (!strcmp(n->name, "r")) { if (n->text != NULL) { WORD nLookFor; hasLookFor = TRUE; nLookFor = atoi(n->text); db_set_w(hContact, proto->m_szModuleName, "LookingFor", nLookFor); } } else if (!strcmp(n->name, "g")) { // voice chat enabled if (n->text != NULL) { BYTE bVoice; bVoice = atoi(n->text); db_set_w(hContact, proto->m_szModuleName, "VoiceChat", bVoice); } } else if (!strcmp(n->name, "v")) { // status visibility if (n->text != NULL) { BYTE bPublic; bPublic = atoi(n->text); db_set_w(hContact, proto->m_szModuleName, "PublicStatus", bPublic); } } } if (!hasFirst) db_unset(hContact, proto->m_szModuleName, "FirstName"); if (!hasLast) db_unset(hContact, proto->m_szModuleName, "LastName"); // We are not removing "Nick" // if (!hasNick) // db_unset(hContact, m_szModuleName, "Nick"); if (!hasEmail) db_unset(hContact, proto->m_szModuleName, "e-mail"); if (!hasCity) db_unset(hContact, proto->m_szModuleName, "City"); if (!hasAge) db_unset(hContact, proto->m_szModuleName, "Age"); if (!hasGender) db_unset(hContact, proto->m_szModuleName, "Gender"); if (!hasSchool) db_unset(hContact, proto->m_szModuleName, "School"); if (!hasOccupation) db_unset(hContact, proto->m_szModuleName, "Occupation"); if (!hasLookFor) db_unset(hContact, proto->m_szModuleName, "LookingFor"); ProtoBroadcastAck(proto->m_szModuleName, hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE) 1, 0); } }
/*========================================================================= DESCRIPTION RFLL1X_IOCTL DEPENDENCIES None RETURN VALUE SIDE EFFECTS None. ===========================================================================*/ rfcom_ioctl_return_type rfll1x_ioctl ( rfll_device_desc_type *dev_desc, rfcom_ioctl_param_type request, void *pbuf, int32 length ) { rfcom_ioctl_return_type err = RFCOM_IOCTL_NO_ERROR; if (pbuf == NULL) { err = RFCOM_IOCTL_NULL_BUFFER; } else { /* Should probably also check that the buffer is large enough to hold data */ switch (request) { case RFCOM_IOCTL_GET_DBG_SCR_TX_AGC: *(int16 *)pbuf = rf_get_cdma_tx_agc(); break; case RFCOM_IOCTL_GET_DBG_SCR_TX_AGC_IN_DBM: *(int16 *)pbuf = rf_get_cdma_tx_agc_in_dBm(); break; case RFCOM_IOCTL_GET_DBG_SCR_TX_ADJ: *(uint8 *)pbuf = rf_get_tx_gain_adj(); break; case RFCOM_IOCTL_GET_DBG_SCR_RX_AGC: *(int16 *)pbuf = rf_get_cdma_rx_agc(); break; case RFCOM_IOCTL_GET_DBG_SCR_RX_AGC_IN_DBM: { int16 ch0_rxagc, ch1_rxagc; ch0_rxagc = rf_get_path_cdma_rx_agc_in_dBm( RFCOM_TRANSCEIVER_0 ); ch1_rxagc = rf_get_path_cdma_rx_agc_in_dBm( RFCOM_RECEIVER_1 ); *(int32 *)pbuf = (ch0_rxagc << 16) | (ch1_rxagc &0xFFFF ); } break; case RFCOM_IOCTL_GET_DBG_SCR_PA_RANGE: *(uint8 *)pbuf = rf_get_pa_state(); break; case RFCOM_IOCTL_GET_DBG_SCR_HDET: *(uint8 *)pbuf = rf_hdet_data; break; case RFCOM_IOCTL_GET_DBG_SCR_LNA_STATE: { uint8 ch0_lna, ch1_lna; ch0_lna = rf_get_path_lna_gain_state(RFCOM_TRANSCEIVER_0); ch1_lna = rf_get_path_lna_gain_state(RFCOM_RECEIVER_1); *(uint8 *)pbuf = (ch0_lna << 4) | (ch1_lna & 0x0F); } break; case RFCOM_IOCTL_GET_DBG_SCR_RATCHET_STATE: *(uint8 *)pbuf = rf_get_ratchet_state(); break; case RFCOM_IOCTL_GET_DBG_SCR_SUPPORTED_HW: *(uint8 *)pbuf = rf_get_rf_hw_config(); break; case RFCOM_IOCTL_GET_DBG_SCR_NV_BAND: *(uint8*)pbuf = rf_get_nv_band(dev_desc->device); break; case RFCOM_IOCTL_GET_DBG_SCR_CHANNEL: { db_items_value_type dbi; db_get(DB_CHANNEL, &dbi); *(uint16 *)pbuf = dbi.channel; } break; case RFCOM_IOCTL_GET_DBG_SCR_BAND_1X: { rf_card_band_type band; uint16 chan; rf_get_band_chan( &band, &chan ); switch (band) { case RF_BC0_BAND: *(rfi_band_type*)pbuf = RFI_CDMA_CELL_BAND; break; case RF_BC1_BAND: *(rfi_band_type*)pbuf = RFI_CDMA_PCS_BAND; break; case RF_BC3_BAND: *(rfi_band_type*)pbuf = RFI_CDMA_BC3_BAND; break; case RF_BC4_BAND: *(rfi_band_type*)pbuf = RFI_CDMA_BC4_BAND; break; case RF_BC5_BAND: *(rfi_band_type*)pbuf = RFI_CDMA_BC5_BAND; break; case RF_BC6_BAND: *(rfi_band_type*)pbuf = RFI_CDMA_BC6_BAND; break; case RF_BC7_BAND: *(rfi_band_type*)pbuf = RFI_CDMA_BC7_BAND; break; case RF_BC8_BAND: *(rfi_band_type*)pbuf = RFI_CDMA_BC8_BAND; break; case RF_BC9_BAND: *(rfi_band_type*)pbuf = RFI_CDMA_BC9_BAND; break; case RF_BC10_BAND: *(rfi_band_type*)pbuf = RFI_CDMA_BC10_BAND; break; case RF_BC11_BAND: *(rfi_band_type*)pbuf = RFI_CDMA_BC11_BAND; break; case RF_BC12_BAND: *(rfi_band_type*)pbuf = RFI_CDMA_BC12_BAND; break; case RF_BC14_BAND: *(rfi_band_type*)pbuf = RFI_CDMA_BC14_BAND; break; case RF_GPS_BAND: *(rfi_band_type*)pbuf = RFI_GPS_BAND; break; default: *(rfi_band_type*)pbuf = RFI_NO_BAND_SEL; break; } } break; case RFCOM_IOCTL_GET_DBG_SCR_INTELLICEIVER_POWER_MODE: #ifdef RF_HAS_POWER_MODE_LIB *(uint8 *)pbuf = rf_intelliceiver_get_power_mode( RF_PATH_0 ); #endif break; case RFCOM_IOCTL_GET_SLEEP_STATE: *(boolean *)pbuf = rf_is_sleeping_cdma1x(dev_desc->device); break; default: err = RFCOM_IOCTL_INVALID_REQUEST; } } return err; }
void TlenIqResultSearch(TlenProtocol *proto, XmlNode *iqNode) { XmlNode *queryNode, *itemNode, *n; char *type, *jid, *str; int id, i, found; TLEN_SEARCH_RESULT jsr = {0}; DBVARIANT dbv = {0}; found = 0; // TlenLog("<iq/> iqIdGetSearch"); if ((type=TlenXmlGetAttrValue(iqNode, "type")) == NULL) return; if ((str=TlenXmlGetAttrValue(iqNode, "id")) == NULL) return; id = atoi(str+strlen(TLEN_IQID)); if (!strcmp(type, "result")) { if ((queryNode=TlenXmlGetChild(iqNode, "query")) == NULL) return; if (!db_get(NULL, proto->m_szModuleName, "LoginServer", &dbv)) { jsr.hdr.cbSize = sizeof(TLEN_SEARCH_RESULT); jsr.hdr.flags = PSR_TCHAR; for (i=0; i<queryNode->numChild; i++) { itemNode = queryNode->child[i]; if (!strcmp(itemNode->name, "item")) { if ((jid=TlenXmlGetAttrValue(itemNode, "jid")) != NULL) { if (strchr(jid, '@') != NULL) { mir_snprintf(jsr.jid, sizeof(jsr.jid), "%s", jid); } else { mir_snprintf(jsr.jid, sizeof(jsr.jid), "%s@%s", jid, dbv.pszVal); } jsr.jid[sizeof(jsr.jid)-1] = '\0'; jsr.hdr.id = mir_a2t(jid); if ((n=TlenXmlGetChild(itemNode, "nick")) != NULL && n->text != NULL){ char* buf = TlenTextDecode(n->text); jsr.hdr.nick = mir_a2t(buf); mir_free(buf); } else { jsr.hdr.nick = mir_tstrdup(TEXT("")); } if ((n=TlenXmlGetChild(itemNode, "first")) != NULL && n->text != NULL){ char* buf = TlenTextDecode(n->text); jsr.hdr.firstName = mir_a2t(buf); mir_free(buf); } else { jsr.hdr.firstName = mir_tstrdup(TEXT("")); } if ((n=TlenXmlGetChild(itemNode, "last")) != NULL && n->text != NULL){ char* buf = TlenTextDecode(n->text); jsr.hdr.lastName = mir_a2t(buf); mir_free(buf); } else { jsr.hdr.lastName = mir_tstrdup(TEXT("")); } if ((n=TlenXmlGetChild(itemNode, "email"))!=NULL && n->text!=NULL){ char* buf = TlenTextDecode(n->text); jsr.hdr.email = mir_a2t(buf); mir_free(buf); } else { jsr.hdr.email = mir_tstrdup(TEXT("")); } ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE) id, (LPARAM) &jsr); found = 1; mir_free(jsr.hdr.id); mir_free(jsr.hdr.nick); mir_free(jsr.hdr.firstName); mir_free(jsr.hdr.lastName); mir_free(jsr.hdr.email); } } } if (proto->searchJID != NULL) { if (!found) { if (strchr(proto->searchJID, '@') != NULL) { mir_snprintf(jsr.jid, sizeof(jsr.jid), "%s", proto->searchJID); } else { mir_snprintf(jsr.jid, sizeof(jsr.jid), "%s@%s", proto->searchJID, dbv.pszVal); } jsr.jid[sizeof(jsr.jid)-1] = '\0'; jsr.hdr.nick = mir_tstrdup(TEXT("")); jsr.hdr.firstName = mir_tstrdup(TEXT("")); jsr.hdr.lastName = mir_tstrdup(TEXT("")); jsr.hdr.email = mir_tstrdup(TEXT("")); jsr.hdr.id = mir_tstrdup(TEXT("")); ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE) id, (LPARAM) &jsr); mir_free(jsr.hdr.nick); mir_free(jsr.hdr.firstName); mir_free(jsr.hdr.lastName); mir_free(jsr.hdr.email); } mir_free(proto->searchJID); proto->searchJID = NULL; } db_free(&dbv); } found = 0; if (queryNode->numChild == TLEN_MAX_SEARCH_RESULTS_PER_PAGE) { found = TlenRunSearch(proto); } if (!found) { ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE) id, 0); } } else if (!strcmp(type, "error")) { // ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE) id, 0); // There is no ACKRESULT_FAILED for ACKTYPE_SEARCH :) look at findadd.c // So we will just send a SUCCESS ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE) id, 0); } }
static INT_PTR CALLBACK TlenUserInfoDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { TLENUSERINFODLGDATA *data = (TLENUSERINFODLGDATA *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: data = (TLENUSERINFODLGDATA*)mir_alloc(sizeof(TLENUSERINFODLGDATA)); data->hContact = (MCONTACT) lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)data); // lParam is hContact TranslateDialogDefault(hwndDlg); InitComboBox(GetDlgItem(hwndDlg, IDC_GENDER), tlenFieldGender); InitComboBox(GetDlgItem(hwndDlg, IDC_OCCUPATION), tlenFieldOccupation); InitComboBox(GetDlgItem(hwndDlg, IDC_LOOKFOR), tlenFieldLookfor); return TRUE; case WM_TLEN_REFRESH: { DBVARIANT dbv; char *jid; int i; TLEN_LIST_ITEM *item; SetDlgItemText(hwndDlg, IDC_INFO_JID, _T("")); SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, _T("")); SetFocus(GetDlgItem(hwndDlg, IDC_STATIC)); if (!db_get_ts(data->hContact, data->proto->m_szModuleName, "FirstName", &dbv)) { SetDlgItemText(hwndDlg, IDC_FIRSTNAME, dbv.ptszVal); db_free(&dbv); } else SetDlgItemText(hwndDlg, IDC_FIRSTNAME, _T("")); if (!db_get_ts(data->hContact, data->proto->m_szModuleName, "LastName", &dbv)) { SetDlgItemText(hwndDlg, IDC_LASTNAME, dbv.ptszVal); db_free(&dbv); } else SetDlgItemText(hwndDlg, IDC_LASTNAME, _T("")); if (!db_get_ts(data->hContact, data->proto->m_szModuleName, "Nick", &dbv)) { SetDlgItemText(hwndDlg, IDC_NICKNAME, dbv.ptszVal); db_free(&dbv); } else SetDlgItemText(hwndDlg, IDC_NICKNAME, _T("")); if (!db_get_ts(data->hContact, data->proto->m_szModuleName, "e-mail", &dbv)) { SetDlgItemText(hwndDlg, IDC_EMAIL, dbv.ptszVal); db_free(&dbv); } else SetDlgItemText(hwndDlg, IDC_EMAIL, _T("")); if (!db_get(data->hContact, data->proto->m_szModuleName, "Age", &dbv)) { SetDlgItemInt(hwndDlg, IDC_AGE, dbv.wVal, FALSE); db_free(&dbv); } else SetDlgItemText(hwndDlg, IDC_AGE, _T("")); if (!db_get_ts(data->hContact, data->proto->m_szModuleName, "City", &dbv)) { SetDlgItemText(hwndDlg, IDC_CITY, dbv.ptszVal); db_free(&dbv); } else SetDlgItemText(hwndDlg, IDC_CITY, _T("")); if (!db_get_ts(data->hContact, data->proto->m_szModuleName, "School", &dbv)) { SetDlgItemText(hwndDlg, IDC_SCHOOL, dbv.ptszVal); db_free(&dbv); } else SetDlgItemText(hwndDlg, IDC_SCHOOL, _T("")); switch (db_get_b(data->hContact, data->proto->m_szModuleName, "Gender", '?')) { case 'M': SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 1, 0); SetDlgItemText(hwndDlg, IDC_GENDER_TEXT, TranslateTS(tlenFieldGender[0].name)); break; case 'F': SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 2, 0); SetDlgItemText(hwndDlg, IDC_GENDER_TEXT, TranslateTS(tlenFieldGender[1].name)); break; default: SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 0, 0); SetDlgItemText(hwndDlg, IDC_GENDER_TEXT, _T("")); break; } i = db_get_w(data->hContact, data->proto->m_szModuleName, "Occupation", 0); if (i>0 && i<13) { SetDlgItemText(hwndDlg, IDC_OCCUPATION_TEXT, TranslateTS(tlenFieldOccupation[i-1].name)); SendDlgItemMessage(hwndDlg, IDC_OCCUPATION, CB_SETCURSEL, i, 0); } else { SetDlgItemText(hwndDlg, IDC_OCCUPATION_TEXT, _T("")); SendDlgItemMessage(hwndDlg, IDC_OCCUPATION, CB_SETCURSEL, 0, 0); } i = db_get_w(data->hContact, data->proto->m_szModuleName, "LookingFor", 0); if (i>0 && i<6) { SetDlgItemText(hwndDlg, IDC_LOOKFOR_TEXT, TranslateTS(tlenFieldLookfor[i-1].name)); SendDlgItemMessage(hwndDlg, IDC_LOOKFOR, CB_SETCURSEL, i, 0); } else { SetDlgItemText(hwndDlg, IDC_LOOKFOR_TEXT, _T("")); SendDlgItemMessage(hwndDlg, IDC_LOOKFOR, CB_SETCURSEL, 0, 0); } i = db_get_w(data->hContact, data->proto->m_szModuleName, "VoiceChat", 0); CheckDlgButton(hwndDlg, IDC_VOICECONVERSATIONS, i ? BST_CHECKED : BST_UNCHECKED); i = db_get_w(data->hContact, data->proto->m_szModuleName, "PublicStatus", 0); CheckDlgButton(hwndDlg, IDC_PUBLICSTATUS, i ? BST_CHECKED : BST_UNCHECKED); if (!db_get(data->hContact, data->proto->m_szModuleName, "jid", &dbv)) { jid = TlenTextDecode(dbv.pszVal); SetDlgItemTextA(hwndDlg, IDC_INFO_JID, jid); mir_free(jid); jid = dbv.pszVal; if (data->proto->isOnline) { if ((item=TlenListGetItemPtr(data->proto, LIST_ROSTER, jid)) != NULL) { switch (item->subscription) { case SUB_BOTH: SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("both")); break; case SUB_TO: SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("to")); break; case SUB_FROM: SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("from")); break; default: SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("none")); break; } SetDlgItemTextA(hwndDlg, IDC_SOFTWARE, item->software); SetDlgItemTextA(hwndDlg, IDC_VERSION, item->version); SetDlgItemTextA(hwndDlg, IDC_SYSTEM, item->system); } else { SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("not on roster")); } } db_free(&dbv); } } break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case 0: switch (((LPNMHDR)lParam)->code) { case PSN_INFOCHANGED: { MCONTACT hContact = (MCONTACT) ((LPPSHNOTIFY) lParam)->lParam; SendMessage(hwndDlg, WM_TLEN_REFRESH, 0, (LPARAM) hContact); } break; case PSN_PARAMCHANGED: { data->proto = ( TlenProtocol* )(( LPPSHNOTIFY )lParam )->lParam; SendMessage(hwndDlg, WM_TLEN_REFRESH, 0, 0); } } break; } break; case WM_COMMAND: if (LOWORD(wParam) == IDC_SAVE && HIWORD(wParam) == BN_CLICKED) { char *str = NULL; int strSize; TlenStringAppend(&str, &strSize, "<iq type='set' id='" TLEN_IQID "%d' to='tuba'><query xmlns='jabber:iq:register'>", TlenSerialNext(data->proto)); FetchField(hwndDlg, IDC_FIRSTNAME, "first", &str, &strSize); FetchField(hwndDlg, IDC_LASTNAME, "last", &str, &strSize); FetchField(hwndDlg, IDC_NICKNAME, "nick", &str, &strSize); FetchField(hwndDlg, IDC_EMAIL, "email", &str, &strSize); FetchCombo(hwndDlg, IDC_GENDER, "s", &str, &strSize); FetchField(hwndDlg, IDC_AGE, "b", &str, &strSize); FetchField(hwndDlg, IDC_CITY, "c", &str, &strSize); FetchCombo(hwndDlg, IDC_OCCUPATION, "j", &str, &strSize); FetchField(hwndDlg, IDC_SCHOOL, "e", &str, &strSize); FetchCombo(hwndDlg, IDC_LOOKFOR, "r", &str, &strSize); TlenStringAppend(&str, &strSize, "<g>%d</g>", IsDlgButtonChecked(hwndDlg, IDC_VOICECONVERSATIONS) ? 1 : 0); TlenStringAppend(&str, &strSize, "<v>%d</v>", IsDlgButtonChecked(hwndDlg, IDC_PUBLICSTATUS) ? 1 : 0); TlenStringAppend(&str, &strSize, "</query></iq>"); TlenSend(data->proto, "%s", str); mir_free(str); data->proto->GetInfo(NULL, 0); } break; case WM_DESTROY: mir_free(data); break; } return FALSE; }
void TlenResultSetRoster(TlenProtocol *proto, XmlNode *queryNode) { DBVARIANT dbv; XmlNode *itemNode, *groupNode; TLEN_LIST_ITEM *item; MCONTACT hContact; char *jid, *name, *nick; int i; char *str; for (i=0; i<queryNode->numChild; i++) { itemNode = queryNode->child[i]; if (!strcmp(itemNode->name, "item")) { if ((jid=TlenXmlGetAttrValue(itemNode, "jid")) != NULL) { str = TlenXmlGetAttrValue(itemNode, "subscription"); if (!strcmp(str, "remove")) { if ((hContact = TlenHContactFromJID(proto, jid)) != NULL) { if (db_get_w(hContact, proto->m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) db_set_w(hContact, proto->m_szModuleName, "Status", ID_STATUS_OFFLINE); } TlenListRemove(proto, LIST_ROSTER, jid); } else { item = TlenListAdd(proto, LIST_ROSTER, jid); if (item != NULL) { if (str == NULL) item->subscription = SUB_NONE; else if (!strcmp(str, "both")) item->subscription = SUB_BOTH; else if (!strcmp(str, "to")) item->subscription = SUB_TO; else if (!strcmp(str, "from")) item->subscription = SUB_FROM; else item->subscription = SUB_NONE; if ((name=TlenXmlGetAttrValue(itemNode, "name")) != NULL) { nick = TlenTextDecode(name); } else { nick = TlenLocalNickFromJID(jid); } if (nick != NULL) { if (item->nick) mir_free(item->nick); item->nick = nick; if ((hContact=TlenHContactFromJID(proto, jid)) == NULL) { // Received roster has a new JID. // Add the jid (with empty resource) to Miranda contact list. hContact = TlenDBCreateContact(proto, jid, nick, FALSE); } db_set_s(hContact, "CList", "MyHandle", nick); if (item->group) mir_free(item->group); if ((groupNode=TlenXmlGetChild(itemNode, "group")) != NULL && groupNode->text != NULL) { item->group = TlenGroupDecode(groupNode->text); Clist_CreateGroup(0, _A2T(item->group)); // Don't set group again if already correct, or Miranda may show wrong group count in some case if (!db_get(hContact, "CList", "Group", &dbv)) { if (strcmp(dbv.pszVal, item->group)) db_set_s(hContact, "CList", "Group", item->group); db_free(&dbv); } else db_set_s(hContact, "CList", "Group", item->group); } else { item->group = NULL; db_unset(hContact, "CList", "Group"); } } } } } } } }
INT_PTR TlenProtocol::MenuHandleInbox(WPARAM, LPARAM) { char szFileName[MAX_PATH]; DBVARIANT dbv; NETLIBHTTPREQUEST req; NETLIBHTTPHEADER headers[2]; NETLIBHTTPREQUEST *resp; char *login = NULL, *password = NULL; char form[1024]; char cookie[1024]; if (!db_get(NULL, m_szModuleName, "LoginName", &dbv)) { login = mir_strdup(dbv.pszVal); db_free(&dbv); } if (db_get_b(NULL, m_szModuleName, "SavePassword", TRUE) == TRUE) password = db_get_sa(NULL, m_szModuleName, "Password"); else if (threadData != NULL && mir_strlen(threadData->password) > 0) password = mir_strdup(threadData->password); memset(&cookie, 0, sizeof(cookie)); if (login != NULL && password != NULL) { mir_snprintf(form, "username=%s&password=%s", login, password); headers[0].szName = "Content-Type"; headers[0].szValue = "application/x-www-form-urlencoded"; memset(&req, 0, sizeof(req)); req.cbSize = sizeof(req); req.requestType = REQUEST_POST; req.flags = 0; req.headersCount = 1; req.headers = headers; req.pData = form; req.dataLength = (int)mir_strlen(form); req.szUrl = "http://poczta.o2.pl/login.html"; resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req); if (resp != NULL) { if (resp->resultCode / 100 == 2 || resp->resultCode == 302) { int i; for (i = 0; i < resp->headersCount; i++) { if (strcmpi(resp->headers[i].szName, "Set-Cookie") == 0) { char *start = strstr(resp->headers[i].szValue, "ssid="); if (start != NULL) { char *end = strstr(resp->headers[i].szValue, ";"); start = start + 5; if (end == NULL) { end = resp->headers[i].szValue + mir_strlen(resp->headers[i].szValue); } strncpy(cookie, start, (end - start)); break; } } } } CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); } } mir_free(login); mir_free(password); mir_snprintf(szFileName, "http://poczta.o2.pl/login.html?sid=%s", cookie); Utils_OpenUrl(szFileName); return 0; }
/* ** COMMAND: merge ** ** Usage: %fossil merge ?OPTIONS? ?VERSION? ** ** The argument VERSION is a version that should be merged into the ** current checkout. All changes from VERSION back to the nearest ** common ancestor are merged. Except, if either of the --cherrypick or ** --backout options are used only the changes associated with the ** single check-in VERSION are merged. The --backout option causes ** the changes associated with VERSION to be removed from the current ** checkout rather than added. ** ** If the VERSION argument is omitted, then Fossil attempts to find ** a recent fork on the current branch to merge. ** ** Only file content is merged. The result continues to use the ** file and directory names from the current checkout even if those ** names might have been changed in the branch being merged in. ** ** Other options: ** ** --baseline BASELINE Use BASELINE as the "pivot" of the merge instead ** of the nearest common ancestor. This allows ** a sequence of changes in a branch to be merged ** without having to merge the entire branch. ** ** --binary GLOBPATTERN Treat files that match GLOBPATTERN as binary ** and do not try to merge parallel changes. This ** option overrides the "binary-glob" setting. ** ** --case-sensitive BOOL Override the case-sensitive setting. If false, ** files whose names differ only in case are taken ** to be the same file. ** ** -f|--force Force the merge even if it would be a no-op. ** ** --force-missing Force the merge even if there is missing content. ** ** --integrate Merged branch will be closed when committing. ** ** -n|--dry-run If given, display instead of run actions ** ** -v|--verbose Show additional details of the merge */ void merge_cmd(void){ int vid; /* Current version "V" */ int mid; /* Version we are merging from "M" */ int pid; /* The pivot version - most recent common ancestor P */ int verboseFlag; /* True if the -v|--verbose option is present */ int integrateFlag; /* True if the --integrate option is present */ int pickFlag; /* True if the --cherrypick option is present */ int backoutFlag; /* True if the --backout option is present */ int dryRunFlag; /* True if the --dry-run or -n option is present */ int forceFlag; /* True if the --force or -f option is present */ int forceMissingFlag; /* True if the --force-missing option is present */ const char *zBinGlob; /* The value of --binary */ const char *zPivot; /* The value of --baseline */ int debugFlag; /* True if --debug is present */ int nChng; /* Number of file name changes */ int *aChng; /* An array of file name changes */ int i; /* Loop counter */ int nConflict = 0; /* Number of conflicts seen */ int nOverwrite = 0; /* Number of unmanaged files overwritten */ Stmt q; /* Notation: ** ** V The current checkout ** M The version being merged in ** P The "pivot" - the most recent common ancestor of V and M. */ undo_capture_command_line(); verboseFlag = find_option("verbose","v",0)!=0; forceMissingFlag = find_option("force-missing",0,0)!=0; if( !verboseFlag ){ verboseFlag = find_option("detail",0,0)!=0; /* deprecated */ } pickFlag = find_option("cherrypick",0,0)!=0; integrateFlag = find_option("integrate",0,0)!=0; backoutFlag = find_option("backout",0,0)!=0; debugFlag = find_option("debug",0,0)!=0; zBinGlob = find_option("binary",0,1); dryRunFlag = find_option("dry-run","n",0)!=0; if( !dryRunFlag ){ dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */ } forceFlag = find_option("force","f",0)!=0; zPivot = find_option("baseline",0,1); verify_all_options(); db_must_be_within_tree(); if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); vid = db_lget_int("checkout", 0); if( vid==0 ){ fossil_fatal("nothing is checked out"); } /* Find mid, the artifactID of the version to be merged into the current ** check-out */ if( g.argc==3 ){ /* Mid is specified as an argument on the command-line */ mid = name_to_typed_rid(g.argv[2], "ci"); if( mid==0 || !is_a_version(mid) ){ fossil_fatal("not a version: %s", g.argv[2]); } }else if( g.argc==2 ){ /* No version specified on the command-line so pick the most recent ** leaf that is (1) not the version currently checked out and (2) ** has not already been merged into the current checkout and (3) ** the leaf is not closed and (4) the leaf is in the same branch ** as the current checkout. */ Stmt q; if( pickFlag || backoutFlag || integrateFlag){ fossil_fatal("cannot use --backout, --cherrypick or --integrate with a fork merge"); } mid = db_int(0, "SELECT leaf.rid" " FROM leaf, event" " WHERE leaf.rid=event.objid" " AND leaf.rid!=%d" /* Constraint (1) */ " AND leaf.rid NOT IN (SELECT merge FROM vmerge)" /* Constraint (2) */ " AND NOT EXISTS(SELECT 1 FROM tagxref" /* Constraint (3) */ " WHERE rid=leaf.rid" " AND tagid=%d" " AND tagtype>0)" " AND (SELECT value FROM tagxref" /* Constraint (4) */ " WHERE tagid=%d AND rid=%d AND tagtype>0) =" " (SELECT value FROM tagxref" " WHERE tagid=%d AND rid=leaf.rid AND tagtype>0)" " ORDER BY event.mtime DESC LIMIT 1", vid, TAG_CLOSED, TAG_BRANCH, vid, TAG_BRANCH ); if( mid==0 ){ fossil_fatal("no unmerged forks of branch \"%s\"", db_text(0, "SELECT value FROM tagxref" " WHERE tagid=%d AND rid=%d AND tagtype>0", TAG_BRANCH, vid) ); } db_prepare(&q, "SELECT blob.uuid," " datetime(event.mtime%s)," " coalesce(ecomment, comment)," " coalesce(euser, user)" " FROM event, blob" " WHERE event.objid=%d AND blob.rid=%d", timeline_utc(), mid, mid ); if( db_step(&q)==SQLITE_ROW ){ char *zCom = mprintf("Merging fork [%S] at %s by %s: \"%s\"", db_column_text(&q, 0), db_column_text(&q, 1), db_column_text(&q, 3), db_column_text(&q, 2)); comment_print(zCom, db_column_text(&q,2), 0, -1, g.comFmtFlags); fossil_free(zCom); } db_finalize(&q); }else{ usage("?OPTIONS? ?VERSION?"); return; } if( zPivot ){ pid = name_to_typed_rid(zPivot, "ci"); if( pid==0 || !is_a_version(pid) ){ fossil_fatal("not a version: %s", zPivot); } if( pickFlag ){ fossil_fatal("incompatible options: --cherrypick & --baseline"); } }else if( pickFlag || backoutFlag ){ if( integrateFlag ){ fossil_fatal("incompatible options: --integrate & --cherrypick or --backout"); } pid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim", mid); if( pid<=0 ){ fossil_fatal("cannot find an ancestor for %s", g.argv[2]); } }else{ pivot_set_primary(mid); pivot_set_secondary(vid); db_prepare(&q, "SELECT merge FROM vmerge WHERE id=0"); while( db_step(&q)==SQLITE_ROW ){ pivot_set_secondary(db_column_int(&q,0)); } db_finalize(&q); pid = pivot_find(); if( pid<=0 ){ fossil_fatal("cannot find a common ancestor between the current " "checkout and %s", g.argv[2]); } } if( backoutFlag ){ int t = pid; pid = mid; mid = t; } if( !is_a_version(pid) ){ fossil_fatal("not a version: record #%d", pid); } if( !forceFlag && mid==pid ){ fossil_print("Merge skipped because it is a no-op. " " Use --force to override.\n"); return; } if( integrateFlag && !is_a_leaf(mid)){ fossil_warning("ignoring --integrate: %s is not a leaf", g.argv[2]); integrateFlag = 0; } if( verboseFlag ){ print_checkin_description(mid, 12, integrateFlag?"integrate:":"merge-from:"); print_checkin_description(pid, 12, "baseline:"); } vfile_check_signature(vid, CKSIG_ENOTFILE); db_begin_transaction(); if( !dryRunFlag ) undo_begin(); if( load_vfile_from_rid(mid) && !forceMissingFlag ){ fossil_fatal("missing content, unable to merge"); } if( load_vfile_from_rid(pid) && !forceMissingFlag ){ fossil_fatal("missing content, unable to merge"); } if( debugFlag ){ char *z; z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pid); fossil_print("P=%d %z\n", pid, z); z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid); fossil_print("M=%d %z\n", mid, z); z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid); fossil_print("V=%d %z\n", vid, z); } /* ** The vfile.pathname field is used to match files against each other. The ** FV table contains one row for each each unique filename in ** in the current checkout, the pivot, and the version being merged. */ db_multi_exec( "DROP TABLE IF EXISTS fv;" "CREATE TEMP TABLE fv(" " fn TEXT PRIMARY KEY %s," /* The filename */ " idv INTEGER," /* VFILE entry for current version */ " idp INTEGER," /* VFILE entry for the pivot */ " idm INTEGER," /* VFILE entry for version merging in */ " chnged BOOLEAN," /* True if current version has been edited */ " ridv INTEGER," /* Record ID for current version */ " ridp INTEGER," /* Record ID for pivot */ " ridm INTEGER," /* Record ID for merge */ " isexe BOOLEAN," /* Execute permission enabled */ " fnp TEXT %s," /* The filename in the pivot */ " fnm TEXT %s," /* the filename in the merged version */ " islinkv BOOLEAN," /* True if current version is a symlink */ " islinkm BOOLEAN" /* True if merged version in is a symlink */ ");", filename_collation(), filename_collation(), filename_collation() ); /* Add files found in V */ db_multi_exec( "INSERT OR IGNORE" " INTO fv(fn,fnp,fnm,idv,idp,idm,ridv,ridp,ridm,isexe,chnged)" " SELECT pathname, pathname, pathname, id, 0, 0, rid, 0, 0, isexe, chnged " " FROM vfile WHERE vid=%d", vid ); /* ** Compute name changes from P->V */ find_filename_changes(pid, vid, 0, &nChng, &aChng, debugFlag ? "P->V" : 0); if( nChng ){ for(i=0; i<nChng; i++){ char *z; z = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2]); db_multi_exec( "UPDATE fv SET fnp=%Q, fnm=%Q" " WHERE fn=(SELECT name FROM filename WHERE fnid=%d)", z, z, aChng[i*2+1] ); free(z); } fossil_free(aChng); db_multi_exec("UPDATE fv SET fnm=fnp WHERE fnp!=fn"); } /* Add files found in P but not in V */ db_multi_exec( "INSERT OR IGNORE" " INTO fv(fn,fnp,fnm,idv,idp,idm,ridv,ridp,ridm,isexe,chnged)" " SELECT pathname, pathname, pathname, 0, 0, 0, 0, 0, 0, isexe, 0 " " FROM vfile" " WHERE vid=%d AND pathname %s NOT IN (SELECT fnp FROM fv)", pid, filename_collation() ); /* ** Compute name changes from P->M */ find_filename_changes(pid, mid, 0, &nChng, &aChng, debugFlag ? "P->M" : 0); if( nChng ){ if( nChng>4 ) db_multi_exec("CREATE INDEX fv_fnp ON fv(fnp)"); for(i=0; i<nChng; i++){ db_multi_exec( "UPDATE fv SET fnm=(SELECT name FROM filename WHERE fnid=%d)" " WHERE fnp=(SELECT name FROM filename WHERE fnid=%d)", aChng[i*2+1], aChng[i*2] ); } fossil_free(aChng); } /* Add files found in M but not in P or V. */ db_multi_exec( "INSERT OR IGNORE" " INTO fv(fn,fnp,fnm,idv,idp,idm,ridv,ridp,ridm,isexe,chnged)" " SELECT pathname, pathname, pathname, 0, 0, 0, 0, 0, 0, isexe, 0 " " FROM vfile" " WHERE vid=%d" " AND pathname %s NOT IN (SELECT fnp FROM fv UNION SELECT fnm FROM fv)", mid, filename_collation() ); /* ** Compute the file version ids for P and M. */ db_multi_exec( "UPDATE fv SET" " idp=coalesce((SELECT id FROM vfile WHERE vid=%d AND fnp=pathname),0)," " ridp=coalesce((SELECT rid FROM vfile WHERE vid=%d AND fnp=pathname),0)," " idm=coalesce((SELECT id FROM vfile WHERE vid=%d AND fnm=pathname),0)," " ridm=coalesce((SELECT rid FROM vfile WHERE vid=%d AND fnm=pathname),0)," " islinkv=coalesce((SELECT islink FROM vfile" " WHERE vid=%d AND fnm=pathname),0)," " islinkm=coalesce((SELECT islink FROM vfile" " WHERE vid=%d AND fnm=pathname),0)", pid, pid, mid, mid, vid, mid ); if( debugFlag ){ db_prepare(&q, "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, " " isexe, islinkv, islinkm FROM fv" ); while( db_step(&q)==SQLITE_ROW ){ fossil_print("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d isexe=%d " " islinkv=%d islinkm=%d\n", db_column_int(&q, 0), db_column_int(&q, 5), db_column_int(&q, 6), db_column_int(&q, 7), db_column_int(&q, 4), db_column_int(&q, 8), db_column_int(&q, 9), db_column_int(&q, 10)); fossil_print(" fn = [%s]\n", db_column_text(&q, 1)); fossil_print(" fnp = [%s]\n", db_column_text(&q, 2)); fossil_print(" fnm = [%s]\n", db_column_text(&q, 3)); } db_finalize(&q); } /* ** Find files in M and V but not in P and report conflicts. ** The file in M will be ignored. It will be treated as if it ** does not exist. */ db_prepare(&q, "SELECT idm FROM fv WHERE idp=0 AND idv>0 AND idm>0" ); while( db_step(&q)==SQLITE_ROW ){ int idm = db_column_int(&q, 0); char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idm); fossil_warning("WARNING - no common ancestor: %s", zName); free(zName); db_multi_exec("UPDATE fv SET idm=0 WHERE idm=%d", idm); } db_finalize(&q); /* ** Add to V files that are not in V or P but are in M */ db_prepare(&q, "SELECT idm, rowid, fnm FROM fv AS x" " WHERE idp=0 AND idv=0 AND idm>0" ); while( db_step(&q)==SQLITE_ROW ){ int idm = db_column_int(&q, 0); int rowid = db_column_int(&q, 1); int idv; const char *zName; char *zFullName; db_multi_exec( "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)" " SELECT %d,%d,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d", vid, integrateFlag?5:3, idm ); idv = db_last_insert_rowid(); db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid); zName = db_column_text(&q, 2); zFullName = mprintf("%s%s", g.zLocalRoot, zName); if( file_wd_isfile_or_link(zFullName) ){ fossil_print("ADDED %s (overwrites an unmanaged file)\n", zName); nOverwrite++; }else{ fossil_print("ADDED %s\n", zName); } fossil_free(zFullName); if( !dryRunFlag ){ undo_save(zName); vfile_to_disk(0, idm, 0, 0); } } db_finalize(&q); /* ** Find files that have changed from P->M but not P->V. ** Copy the M content over into V. */ db_prepare(&q, "SELECT idv, ridm, fn, islinkm FROM fv" " WHERE idp>0 AND idv>0 AND idm>0" " AND ridm!=ridp AND ridv=ridp AND NOT chnged" ); while( db_step(&q)==SQLITE_ROW ){ int idv = db_column_int(&q, 0); int ridm = db_column_int(&q, 1); const char *zName = db_column_text(&q, 2); int islinkm = db_column_int(&q, 3); /* Copy content from idm over into idv. Overwrite idv. */ fossil_print("UPDATE %s\n", zName); if( !dryRunFlag ){ undo_save(zName); db_multi_exec( "UPDATE vfile SET mtime=0, mrid=%d, chnged=%d, islink=%d " " WHERE id=%d", ridm, integrateFlag?4:2, islinkm, idv ); vfile_to_disk(0, idv, 0, 0); } } db_finalize(&q); /* ** Do a three-way merge on files that have changes on both P->M and P->V. */ db_prepare(&q, "SELECT ridm, idv, ridp, ridv, %s, fn, isexe, islinkv, islinkm FROM fv" " WHERE idp>0 AND idv>0 AND idm>0" " AND ridm!=ridp AND (ridv!=ridp OR chnged)", glob_expr("fv.fn", zBinGlob) ); while( db_step(&q)==SQLITE_ROW ){ int ridm = db_column_int(&q, 0); int idv = db_column_int(&q, 1); int ridp = db_column_int(&q, 2); int ridv = db_column_int(&q, 3); int isBinary = db_column_int(&q, 4); const char *zName = db_column_text(&q, 5); int isExe = db_column_int(&q, 6); int islinkv = db_column_int(&q, 7); int islinkm = db_column_int(&q, 8); int rc; char *zFullPath; Blob m, p, r; /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ if( verboseFlag ){ fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n", zName, ridp, ridm, ridv); }else{ fossil_print("MERGE %s\n", zName); } if( islinkv || islinkm /* || file_wd_islink(zFullPath) */ ){ fossil_print("***** Cannot merge symlink %s\n", zName); nConflict++; }else{ undo_save(zName); zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); content_get(ridp, &p); content_get(ridm, &m); if( isBinary ){ rc = -1; blob_zero(&r); }else{ unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0; rc = merge_3way(&p, zFullPath, &m, &r, mergeFlags); } if( rc>=0 ){ if( !dryRunFlag ){ blob_write_to_file(&r, zFullPath); file_wd_setexe(zFullPath, isExe); } db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv); if( rc>0 ){ fossil_print("***** %d merge conflicts in %s\n", rc, zName); nConflict++; } }else{ fossil_print("***** Cannot merge binary file %s\n", zName); nConflict++; } blob_reset(&p); blob_reset(&m); blob_reset(&r); } db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(%d,%d)", idv,ridm); } db_finalize(&q); /* ** Drop files that are in P and V but not in M */ db_prepare(&q, "SELECT idv, fn, chnged FROM fv" " WHERE idp>0 AND idv>0 AND idm=0" ); while( db_step(&q)==SQLITE_ROW ){ int idv = db_column_int(&q, 0); const char *zName = db_column_text(&q, 1); int chnged = db_column_int(&q, 2); /* Delete the file idv */ fossil_print("DELETE %s\n", zName); if( chnged ){ fossil_warning("WARNING: local edits lost for %s\n", zName); nConflict++; } undo_save(zName); db_multi_exec( "UPDATE vfile SET deleted=1 WHERE id=%d", idv ); if( !dryRunFlag ){ char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName); file_delete(zFullPath); free(zFullPath); } } db_finalize(&q); /* ** Rename files that have taken a rename on P->M but which keep the same ** name o P->V. If a file is renamed on P->V only or on both P->V and ** P->M then we retain the V name of the file. */ db_prepare(&q, "SELECT idv, fnp, fnm FROM fv" " WHERE idv>0 AND idp>0 AND idm>0 AND fnp=fn AND fnm!=fnp" ); while( db_step(&q)==SQLITE_ROW ){ int idv = db_column_int(&q, 0); const char *zOldName = db_column_text(&q, 1); const char *zNewName = db_column_text(&q, 2); fossil_print("RENAME %s -> %s\n", zOldName, zNewName); undo_save(zOldName); undo_save(zNewName); db_multi_exec( "UPDATE vfile SET pathname=%Q, origname=coalesce(origname,pathname)" " WHERE id=%d AND vid=%d", zNewName, idv, vid ); if( !dryRunFlag ){ char *zFullOldPath = mprintf("%s%s", g.zLocalRoot, zOldName); char *zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName); if( file_wd_islink(zFullOldPath) ){ symlink_copy(zFullOldPath, zFullNewPath); }else{ file_copy(zFullOldPath, zFullNewPath); } file_delete(zFullOldPath); free(zFullNewPath); free(zFullOldPath); } } db_finalize(&q); /* Report on conflicts */ if( nConflict ){ fossil_warning("WARNING: %d merge conflicts", nConflict); } if( nOverwrite ){ fossil_warning("WARNING: %d unmanaged files were overwritten", nOverwrite); } if( dryRunFlag ){ fossil_warning("REMINDER: this was a dry run -" " no files were actually changed."); } /* ** Clean up the mid and pid VFILE entries. Then commit the changes. */ db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid); if( pickFlag ){ db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-1,%d)",mid); /* For a cherry-pick merge, make the default check-in comment the same ** as the check-in comment on the check-in that is being merged in. */ db_multi_exec( "REPLACE INTO vvar(name,value)" " SELECT 'ci-comment', coalesce(ecomment,comment) FROM event" " WHERE type='ci' AND objid=%d", mid ); }else if( backoutFlag ){ db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-2,%d)",pid); }else if( integrateFlag ){ db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-4,%d)",mid); }else{ db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid); } undo_finish(); db_end_transaction(dryRunFlag); }