Форум: "Базы";
Текущий архив: 2003.07.24;
Скачать: [xml.tar.bz2];
ВнизКак можно получить список пользователей подключенных к серверу? Найти похожие ветки
← →
Cranium (2003-06-30 18:50) [0]Как можно получить список пользователей подключенных к серверу?
← →
Zacho (2003-06-30 19:48) [1]Смотри TIBDatabaseInfo.UserNames Но это будет работать только на SuperServer. На Classic - никак не получишь.
← →
XanderMan (2003-06-30 19:51) [2]> Zacho
Так можно получить список всех пользователей на сервере, а нужны, насколько я понял, только те, кто в данный момент подключен к серверу.
← →
Zacho (2003-06-30 20:02) [3]
> XanderMan © (30.06.03 19:51)
Разве ? А хелп уверяет, что это список пользователей, в данный момент подключенных к конкретной БД (даже не к серверу, а именно к БД !) Врет ?
← →
XanderMan (2003-06-30 20:05) [4]Пару недель назад полдня бился над тем же вопросом!
Врет хелп :-(
← →
Zacho (2003-06-30 20:32) [5]
> XanderMan © (30.06.03 20:05)
А у меня - не врет. IBX 6.0(?) (в общем, версия к-рая шла с Д6 без всяких апдейтов).
Так что 3 варианта:
1. У тебя IB Classic
2. Баг в твоей версии IBX
3. Баг в твоей программе.
← →
Zacho (2003-06-30 20:42) [6]
> Zacho © (30.06.03 20:32)
Небольшое дополнение. 1-й вариант - вряд ли, насколько понимаю, в этом случае ты получишь только имя пользователя текущего подключения.
Еще один вариант (бредовый) : ты перепутал TIBDatabaseInfo c чем-то другим :-)
← →
XanderMan (2003-06-30 22:21) [7]>Zacho
Переклинило. Перерыл всю палитру компонентов InterbaseAdmin в поиске сабжа и не подумал о том, что он может содержаться в IBX. Так что твой последний пост оказался совершенно правильным. Перепутал (а точнее не обратил внимание на этот компонент). Спасибо, что вразумил.
Только одно маленькое замечание: TIBDatabaseInfo выдает список пользователей, подключенных к конкретной базе, а не к серверу в целом.
С уважением
← →
Cranium (2003-06-30 22:30) [8]Да вы тут спорите, а у меня получается с помощью TIBDatabaseInfo получить только текущего пользователя...
Может я чего не догоняю....
← →
Cranium (2003-06-30 22:32) [9]В принце
> Только одно маленькое замечание: TIBDatabaseInfo выдает
> список пользователей, подключенных к конкретной базе, а
> не к серверу в целом.
Это даже лучьше...
← →
Zacho (2003-06-30 23:12) [10]
> XanderMan © (30.06.03 22:21)
> Только одно маленькое замечание: TIBDatabaseInfo выдает
> список пользователей, подключенных к конкретной базе, а
> не к серверу в целом.
Дык, я об этом и писал. А что переклинило - бывает :), у меня тоже недавно подобное было :)
> Cranium © (30.06.03 22:30)
Значит, у тебя Classic. Тогда - нормальных способов получения списка поключившихся пользователей нет. Можешь посмотреть статью http://www.volny.cz/iprenosil/interbase/ip_ib_isc4.htm - насколько помню, там был способ ведения лога пользователей. И другие извращения с isc4.gdb
← →
Cranium (2003-06-30 23:21) [11]
> http://www.volny.cz/iprenosil/interbase/ip_ib_isc4.htm
Я это читал.... В свою очередь родилась мысль не проверенная пока на практике, а что если
таблицу RDB$USER_PRIVILEGES тоже подменить VIEW, тогда можно
регистрировать попытки просмотра, редактирования и т.д. таблиц и т.д...
← →
Cranium (2003-06-30 23:32) [12]
> Zacho © (30.06.03 23:12)
> Значит, у тебя Classic.
Заменил CS на SS, работает...
> Тогда - нормальных способов получения списка поключившихся
> пользователей нет
Неужели так плохо...:((
← →
Zacho (2003-06-30 23:32) [13]
> Cranium © (30.06.03 23:21)
Мысль интересная, но не думаю, что получится.
А самое простое и радикальное решение - перейти с классика на суперсервер. Еще можно сделать трехзвенку, и соответственно регистрацию пользователей на сервере приложений. Можно, наверное, и еще что-нибудь придумать. Только так ли нужен вообще этот список пользователей ?
← →
Cranium (2003-07-01 16:54) [14]
> Zacho © (30.06.03 23:32)
> Мысль интересная, но не думаю, что получится.
Если хочешь сообщу о результатах...
> А самое простое и радикальное решение - перейти с классика
> на суперсервер
Пишу базу под свою контору, а у нас уже есть много процессорные сервера, а CS наилучьшее решение в данном случае....
> Только так ли нужен вообще этот список пользователей ?
Лично мне нет, а вот руководство желает.....
← →
Zacho (2003-07-01 18:03) [15]
> Cranium © (01.07.03 16:54)
> Если хочешь сообщу о результатах...
Хочу.
> Пишу базу под свою контору, а у нас уже есть много процессорные
> сервера, а CS наилучьшее решение в данном случае....
Согласен.
> Лично мне нет, а вот руководство желает.....
Поробуй объяснить руководству, что на это уйдет, как минимум, довольно много рабочего времени, и, соответственно, денег. А стоит ли оно того ?
← →
Jedi K (2003-07-01 18:56) [16]program IB_SHOWUSERS;
{$APPTYPE CONSOLE}
{ Compiled with Delphi4 (UP3) }
uses Windows, SysUtils;
const
isc_dpb_version1 = 1;
isc_dpb_user_name = 28;
isc_dpb_password = 29;
isc_info_end = 1;
isc_info_truncated = 2;
isc_info_error = 3;
isc_info_user_names = 53;
IBASE_DLL = "GDS32.DLL";
KILOBYTE = 1024;
type
ISC_LONG = Longint;
ISC_STATUS = ISC_LONG;
ISC_STATUS_VECTOR = array[0..19] of ISC_STATUS;
PSTATUS_VECTOR = ^ISC_STATUS_VECTOR;
PPSTATUS_VECTOR = ^PSTATUS_VECTOR;
Tisc_db_handle = Pointer;
pisc_db_handle = ^Tisc_db_handle;
TParamBlock = array [0..KILOBYTE-1] of Char;
TLargePB = array [0..(4*KILOBYTE)-1] of Char;
TSmallPB = array [0..(KILOBYTE div 4)-1] of Char;
function isc_interprete(buffer: PChar; status_vector_ptr: PPSTATUS_VECTOR): ISC_STATUS;
stdcall; external IBASE_DLL name "isc_interprete";
function isc_attach_database(status_vector: PSTATUS_VECTOR; db_name_length: Short;
db_name: PChar; db_handle: pisc_db_handle; parm_buffer_length: Short;
parm_buffer: PChar): ISC_STATUS; stdcall; external IBASE_DLL name "isc_attach_database";
function isc_database_info(status_vector: PSTATUS_VECTOR; db_handle: pisc_db_handle;
item_list_buffer_length: Smallint; item_list_buffer: Pointer;
result_buffer_length: Smallint; result_buffer: Pointer): ISC_STATUS;
stdcall; external IBASE_DLL name "isc_database_info";
function isc_vax_integer(result_buffer : PChar; result_length : SmallInt): ISC_LONG;
stdcall; external IBASE_DLL name "isc_vax_integer";
function isc_detach_database(status_vector: PSTATUS_VECTOR; db_handle:
pisc_db_handle): ISC_STATUS; stdcall; external IBASE_DLL name "isc_detach_database";
var
UserFound: boolean;
Mode: (mdDBName, mdUserName, mdPassword);
s, DBName, UserName, Password: string;
ErrorCode: ISC_STATUS;
StatusVector: ISC_STATUS_VECTOR;
DBHandle: Tisc_db_handle;
DPB: TParamBlock; //parameter block for database connection
DPBLen: Integer; //length of Paramblock
ItemList: TSmallPB;
UserNames: TLargePB;
UserCount: Integer;
i: Integer;
Item, //InfoItem we are testing for
Pos, //marker for position in array
Len, //Length of section
namelength: SmallInt;
UserStr: array[0..255] of char;
procedure Error;
var
buffer: array[0..511] of char;
ErrorMessages, lastMsg: string;
pStatus: PSTATUS_VECTOR;
begin
fillchar(buffer,512,#0);
pStatus:=@StatusVector;
ErrorMessages:="";
repeat
ErrorCode := isc_interprete( @buffer, @pstatus);
if lastMsg <> strPas( buffer) then
begin
lastMsg := strPas( buffer);
if length(ErrorMessages) <> 0 then ErrorMessages := ErrorMessages+#13#10;
ErrorMessages := ErrorMessages+lastMsg;
end;
until ErrorCode = 0;
raise Exception.Create(ErrorMessages);
end;
procedure BuildPBString( var PB: array of char; var PBLen: Integer; item: byte; contents: string);
//Add a string value to a parameter block
var len: Integer;
begin
{PBLen is the current size of the populated array, as well as the indicator}
PB[PBLen] := char(item);
inc(PBLen);
len:=Length(Contents);
PB[PBLen] := char(len);
inc(PBLen);
StrPCopy(@PB[PBLen],Contents);
inc(PBLen,len);
end;
← →
Jedi K (2003-07-01 18:57) [17]begin
try
UserFound := false;
Mode := mdDBName;
DBName := "";
UserName := "";
Password := "";
for i := 1 to paramcount do
begin
s := paramstr(i);
if s[1] = "-" then
case upcase(s[2]) of
"U":
begin
Mode := mdUserName;
delete(s, 1, 2);
end;
"P":
begin
Mode := mdPassword;
delete(s, 1, 2);
end;
end;
if s <> "" then
begin
case Mode of
mdDBName: DBName := s;
mdUserName: UserName := s;
mdPassword: Password := s;
end;
Mode := mdDBName
end;
end;
if (DBName = "") or (UserName = "") then
begin
writeln("IB_SHOWUSERS is a console mode program that lists all users currently");
writeln("connected to a database.");
writeln("IB_SHOWUSERS is freeware and comes AS-IS. Use it on your own risk.");
writeln("IB_SHOWUSERS has been tested with Interbase V5.5 on Windows 95/NT4.");
writeln("V1.0, Author: Karsten Strobel");
writeln;
writeln("Usage:");
writeln("IB_SHOWUSERS -U username -P password path-to-database");
halt(2);
end;
for i:=low(StatusVector) to high(StatusVector) do StatusVector[i] := 0;
DBHandle := nil;
fillchar(DPB,sizeof(DPB),#0);
DPB[0] := char(isc_dpb_version1);
DPBLen := 1;
BuildPBString(DPB,DPBLen,isc_dpb_user_name,Username);
BuildPBString(DPB,DPBLen,isc_dpb_password,Password);
ErrorCode := isc_attach_database(@StatusVector, Length(DBName), PChar(DBName),
@DBHandle, DPBLen, @DPB);
if ErrorCode <> 0 then
begin
Error;
halt;
end;
fillchar(itemlist, sizeof(itemlist),#0);
ItemList[0] := char(isc_info_user_names);
fillchar(UserNames, sizeof(UserNames),#0);
ErrorCode := isc_database_info(@StatusVector, @DBHandle, 1, @itemlist, 1024, @UserNames);
if ErrorCode = 0 then
begin
(* Usernames will now have data in the following format:
"5", //Info type - isc_info_user_name
#6, #0, //Number of bytes in next section
#5, //length of name
"G", "U", "E", "S", "T", //name
"5", //Info type - isc_info_user_name
#7, #0, //Number of bytes in next section
#6, //length of name
"S", "Y", "S", "D", "B", "A", //name
etc. etc.
#1, //isc_info_end (hopefully)
*)
writeln("The following users are currently connected:"#13#10);
item:=0;
UserCount:=0;
while not ((((UserNames[item])=char(isc_info_end)) or
((UserNames[item])=char(isc_info_error))) or
((UserNames[item])=char(isc_info_truncated))) do
begin
pos:=item; //isc_info_user_name
inc(pos); //start of length byte pair
len := isc_vax_integer(@UserNames[pos],2); //read the two-byte length and save it for Ron.
inc(pos,2); //move forward to byte telling us length of name
UserStr:="";
NameLength:=byte(UserNames[pos])+1;
fillChar(UserStr,256,#0);
for i:=1 to namelength-1 do UserStr[i-1] := UserNames[pos+i];
write(UserStr);
if not UserFound and (AnsiCompareText(UserName, UserStr) = 0) then
begin
UserFound := true;
write(" (this program)");
end;
writeln;
inc(UserCount);
inc(item,len+3);{move to next item (3 covers length of item (one byte) and len (two bytes)}
end;
write(#13#10, IntToStr(UserCount)," user");
if UserCount > 1 then write("s");
writeln;
exitcode := ord(UserCount > 1);
end
else Error;
if assigned(DBHandle) then
begin
ErrorCode := isc_detach_database(@StatusVector, @DBHandle);
if ErrorCode <> 0 then Error;
end;
except
on E:Exception do
begin
s := E.Message + #13#10;
WriteFile(GetStdHandle(STD_ERROR_HANDLE), s[1], Length(s), DWORD(i), nil);
ExitCode := 2;
end;
end;
end.
← →
Cranium (2003-07-01 19:23) [18]
> Jedi K (01.07.03 18:56)
Большое спасибо!
Но хотелось бы немного коментария.. К выше изложеному коду
← →
Zacho (2003-07-01 20:26) [19]
> Jedi K (01.07.03 18:56)
Ага, так оно и заработало на Classic :-P
Тоже самое, что и TIBDatabaseInfo
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.07.24;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.009 c