Пример #1
0
/*
 * 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);
}
Пример #2
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
}
Пример #3
0
/*
 * 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);
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
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);
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
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);
		}
	}
}
Пример #10
0
/*
 * 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);
}
Пример #11
0
/*
 * 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);
}
Пример #12
0
/*
 * 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);
}
Пример #13
0
/*
** 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");
    }
}
Пример #14
0
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;
}
Пример #15
0
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);
}
Пример #17
0
/*
 * 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);
}
Пример #18
0
/*
 * 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);
}
Пример #19
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);
}
Пример #20
0
/*
 * 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);
}
Пример #21
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);
}
Пример #22
0
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);
		}
	}
}
Пример #23
0
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);
}
Пример #24
0
// 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);
	}
}
Пример #25
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;
}
Пример #26
0
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);
	}
}
Пример #27
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;
}
Пример #28
0
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");
							}
						}
					}
				}
			}
		}
	}
}
Пример #29
0
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;
}
Пример #30
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);
}