2003.08.12 (火) 00:57:24 <Heracules> usj氏のコード(24183,24184参照)を流用することで負荷をあまり気にしなくてもよくなりました。
2003.08.12 (火) 00:58:07 <Heracules> 211123ではログイン時に単一スレッドにて処理していましたが、211127では、IPからリモートホストへの変換にひとつスレッドを作っています。
2003.08.12 (火) 00:58:50 <Heracules> また、24184をさらに発展させて、同時に取得処理できるリモートホスト数を設定できるようにしました。
2003.08.12 (火) 00:59:18 <Heracules> デフォルト値は3です。1〜100の範囲で指定できるようにしましたが、あまり増やさない方がいいかもしれません。
shuusei211127:ユーザリストへのリモートホストの表示を再実装(shuusei211123,24183,24184参照)

diff --dos -urN 211126/settings.pas 211127/settings.pas
--- 211126/settings.pas	Mon Aug 11 00:55:16 2003
+++ 211127/settings.pas	Tue Aug 12 00:43:52 2003
@@ -581,8 +581,12 @@
     cb_2byte_id_enabled: TCheckBox;
     cb_2byte_channel_enabled: TCheckBox;
     cb_channels_timestamp: TCheckBox;
-    cb_ul_gethost: TCheckBox;
     cb_suggest_dbrowse: TCheckBox;
+    cb_whois_gethost: TCheckBox;
+    edit_ul_gethost_max_resolving_cnt: TSpinEdit;
+    Label149: TLabel;
+    Label150: TLabel;
+    Label151: TLabel;
     procedure Panel3Resize(Sender: TObject);
     procedure headerPaint(Sender: TObject);
     procedure SetTopText(str: String);
@@ -1508,7 +1512,10 @@
   cb_2byte_id_enabled.Checked:=id_2byte_enabled;
   cb_2byte_channel_enabled.Checked:=channel_2byte_enabled;
   ini:=TIniFile.Create(ApplicationDir+'config');
-  cb_ul_gethost.Checked:=ul_gethost;
+  cb_whois_gethost.Checked:=whois_gethost;
+  ini:=TIniFile.Create(ApplicationDir+'config');
+    edit_ul_gethost_max_resolving_cnt.Value:=ini.ReadInteger('Interface','UsersListHideRemoteHostMaxResolvingCount',3);
+  ini.Free;
 end;
 
 procedure TSlavaNapSettings.sh_reportShow(Sender: TObject);
@@ -2019,8 +2026,11 @@
    allowed_custom[4]:=edit_allow_sign4.Text;
    id_2byte_enabled:=cb_2byte_id_enabled.Checked;
    channel_2byte_enabled:=cb_2byte_channel_enabled.Checked;
-   ul_gethost:=cb_ul_gethost.Checked;
+   whois_gethost:=cb_whois_gethost.Checked;
    suggest_dbrowse:=cb_suggest_dbrowse.Checked;
+   ini:=TIniFile.Create(ApplicationDir+'config');
+     ini.WriteInteger('Interface','UsersListHideRemoteHostMaxResolvingCount',edit_ul_gethost_max_resolving_cnt.Value);
+   ini.Free;
   except
  end else if pages.ActivePage=sh_report then
  try
diff --dos -urN 211126/settings.dfm 211127/settings.dfm
--- 211126/settings.dfm	Mon Aug 11 00:52:38 2003
+++ 211127/settings.dfm	Tue Aug 12 00:44:14 2003
@@ -2331,7 +2331,7 @@
           Width = 111
           Height = 20
           Style = csDropDownList
-          ItemHeight = 0
+          ItemHeight = 12
           TabOrder = 1
         end
       end
@@ -5680,7 +5680,7 @@
           Width = 66
           Height = 20
           Style = csDropDownList
-          ItemHeight = 0
+          ItemHeight = 12
           TabOrder = 5
         end
         object Panel4: TPanel
@@ -5731,7 +5731,7 @@
           Width = 66
           Height = 20
           Style = csDropDownList
-          ItemHeight = 0
+          ItemHeight = 12
           TabOrder = 7
         end
         object Panel5: TPanel
@@ -5791,7 +5791,7 @@
           Width = 66
           Height = 20
           Style = csDropDownList
-          ItemHeight = 0
+          ItemHeight = 12
           TabOrder = 10
         end
         object cb_loginblock_port: TCheckBox
@@ -5860,6 +5860,27 @@
         ImageIndex = 30
         TabVisible = False
         OnShow = sh_other4Show
+        object Label149: TLabel
+          Left = 8
+          Top = 170
+          Width = 203
+          Height = 12
+          Caption = 'ユーザリストにホスト名を表示するときに'
+        end
+        object Label150: TLabel
+          Left = 72
+          Top = 184
+          Width = 153
+          Height = 12
+          Caption = '同時に解決するホストの個数:'
+        end
+        object Label151: TLabel
+          Left = 288
+          Top = 184
+          Width = 56
+          Height = 12
+          Caption = '(要再起動)'
+        end
         object cb_WindowClose: TCheckBox
           Left = 6
           Top = 4
@@ -6010,21 +6031,31 @@
           Caption = '2バイト文字のチャンネル名への使用を認める'
           TabOrder = 17
         end
-        object cb_ul_gethost: TCheckBox
+        object cb_suggest_dbrowse: TCheckBox
           Left = 8
           Top = 136
-          Width = 225
+          Width = 337
           Height = 17
-          Caption = 'ユーザ情報所得時にホスト名も表示する'
+          Caption = 'クライアント間で直接参照が可能な場合に使用するように促す'
           TabOrder = 18
         end
-        object cb_suggest_dbrowse: TCheckBox
+        object cb_whois_gethost: TCheckBox
           Left = 8
           Top = 152
-          Width = 337
+          Width = 329
           Height = 17
-          Caption = 'クライアント間で直接参照が可能な場合に使用するように促す'
+          Caption = 'Whois命令で得られる情報にホスト名を追加する(mod+限定)'
           TabOrder = 19
+        end
+        object edit_ul_gethost_max_resolving_cnt: TSpinEdit
+          Left = 224
+          Top = 176
+          Width = 57
+          Height = 21
+          MaxValue = 100
+          MinValue = 1
+          TabOrder = 20
+          Value = 0
         end
       end
     end
diff --dos -urN 211126/console.pas 211127/console.pas
--- 211126/console.pas	Mon Aug 11 02:43:14 2003
+++ 211127/console.pas	Tue Aug 12 00:09:42 2003
@@ -398,6 +398,7 @@
  str,f: String;
  b: Boolean;
  t: time_t;
+ th: TUserListReverseDNSThread;
 begin
  if not running then exit;
  SlavaNapWindow.btn_users_refresh.Enabled:=true;
@@ -449,6 +450,13 @@
       item.SubItems.Add(user^.software);
       item.SubItems.Add(Speed2Str(user^.speed));
       item.SubItems.Add(decode_ip(user^.ip));
+      item.SubItems.Add('Unresolved');
+      if SlavaNapWindow.isColumnVisible(SlavaNapWindow.list_users,UL_REMOTEHOST+1) then
+      begin
+        th:=TUserListReverseDNSThread.Create(False);
+        th.ip:=user^.ip;
+        th.item:=item;
+      end;
       item.SubItems.Add(IntToStr(user^.dataport));
       item.SubItems.Add(Time2Str(t-user^.last_seen));
       item.SubItems.Add(IntToStr(user^.uploads));
diff --dos -urN 211126/constants.pas 211127/constants.pas
--- 211126/constants.pas	Mon Aug 11 00:46:50 2003
+++ 211127/constants.pas	Mon Aug 11 23:31:36 2003
@@ -156,16 +156,17 @@
  UL_SOFT                      = 4;
  UL_SPEED                     = 5;
  UL_IP                        = 6;
- UL_PORT                      = 7;
- UL_TIME                      = 8;
- UL_UP                        = 9;
- UL_DOWN                      = 10;
- UL_TRANSFERS                 = 11;
- UL_TUP                       = 12;
- UL_TDOWN                     = 13;
- UL_TTRANSFERS                = 14;
- UL_SERVER                    = 15;
- UL_STATUS                    = 16;
+ UL_REMOTEHOST                = 7;
+ UL_PORT                      = 8;
+ UL_TIME                      = 9;
+ UL_UP                        = 10;
+ UL_DOWN                      = 11;
+ UL_TRANSFERS                 = 12;
+ UL_TUP                       = 13;
+ UL_TDOWN                     = 14;
+ UL_TTRANSFERS                = 15;
+ UL_SERVER                    = 16;
+ UL_STATUS                    = 17;
 
 MSG_SERVER_ERROR		= 0;
 MSG_CLIENT_LOGIN		= 2;
diff --dos -urN 211126/mainform.pas 211127/mainform.pas
--- 211126/mainform.pas	Mon Aug 11 14:30:02 2003
+++ 211127/mainform.pas	Tue Aug 12 01:25:22 2003
@@ -402,6 +402,7 @@
     mnu_um_totalup: TMenuItem;
     mnu_um_totaldown: TMenuItem;
     mnu_users_announce: TMenuItem;
+    mnu_um_remotehost: TMenuItem;
     edit_users_autoreftime: TSpinEdit;
     Label1: TLabel;
     cb_users_autoref: TCheckBox;
@@ -583,6 +584,7 @@
     function  CompareTime(str1,str2: String): Integer;
     function  CompareDigit(str1,str2: String): Integer;
     function  CompareSpeed(str1,str2: String): Integer;
+    function  CompareRemoteHost(str1,str2: String): Integer;
     procedure AppException(Sender: TObject; E: Exception);
     procedure SetBanItems(control: TComboBox);
     function  GetBanID(control: TComboBox): Integer;
@@ -1164,7 +1166,9 @@
   if ini.ReadBool('Interface','UsersListHideTotalDown',true) then begin isHide[UL_TDOWN+1]:=true; SetColumnVisible(list_users,UL_TDOWN+1,0,false); end;
   if ini.ReadBool('Interface','UsersListHideTotal',true) then begin isHide[UL_TTRANSFERS+1]:=true; SetColumnVisible(list_users,UL_TTRANSFERS+1,0,false); end;
   if ini.ReadBool('Interface','UsersListHideServer',false) then begin isHide[UL_SERVER+1]:=true; SetColumnVisible(list_users,UL_SERVER+1,0,false); end;
-  ul_gethost:=ini.ReadBool('Interface','UsersListGetHost',false);
+  if ini.ReadBool('Interface','UsersListHideRemoteHost',true) then begin isHide[UL_REMOTEHOST+1]:=true; SetColumnVisible(list_users,UL_REMOTEHOST+1,0,false); end;
+  ul_gethost_max_resolving_cnt:=ini.ReadInteger('Interface','UsersListHideRemoteHostMaxResolvingCount',3);
+  whois_gethost:=ini.ReadBool('Interface','WhoisGetHost',false);
   // colors
   LogStartup('mainform::loadconfig: loading colors');
   slBackground:=ini.ReadInteger('Colors','clBackground',$FFFFFF);
@@ -1672,7 +1676,8 @@
   ini.WriteBool('Interface','UsersListHideTotalDown',not isColumnVisible(list_users,UL_TDOWN+1));
   ini.WriteBool('Interface','UsersListHideTotal',not isColumnVisible(list_users,UL_TTRANSFERS+1));
   ini.WriteBool('Interface','UsersListHideServer',not isColumnVisible(list_users,UL_SERVER+1));
-  ini.WriteBool('Interface','UsersListGetHost',ul_gethost);
+  ini.WriteBool('Interface','UsersListHideRemoteHost',not isColumnVisible(list_users,UL_REMOTEHOST+1));
+  ini.WriteBool('Interface','WhoisGetHost',whois_gethost);
   // colors
   ini.WriteInteger('Colors','clBackground',slBackground);
   ini.WriteInteger('Colors','clText',slText);
@@ -2168,6 +2173,7 @@
  mnu_um_soft.Caption:=GetLangI(LNG_LIST_MNU2_SOFT);
  mnu_um_speed.Caption:=GetLangI(LNG_LIST_MNU2_SPEED);
  mnu_um_ip.Caption:=GetLangI(LNG_LIST_MNU2_IP);
+ mnu_um_remotehost.Caption:='リモートホストを表示';
  mnu_um_port.Caption:=GetLangI(LNG_LIST_MNU2_PORT);
  mnu_um_time.Caption:=GetLangI(LNG_LIST_MNU2_TIME);
  mnu_um_up.Caption:='アップロード数を表示';
@@ -2253,6 +2259,7 @@
    Items[UL_SOFT+1].Caption:=GetLangI(LNG_LIST_HEADER_SOFTWARE);
    Items[UL_SPEED+1].Caption:=GetLangI(LNG_LIST_HEADER_SPEED);
    Items[UL_IP+1].Caption:=GetLangI(LNG_LIST_HEADER_IP);
+   Items[UL_REMOTEHOST+1].Caption:='リモートホスト';
    Items[UL_PORT+1].Caption:=GetLangI(LNG_LIST_HEADER_PORT);
    Items[UL_TIME+1].Caption:=GetLangI(LNG_LIST_HEADER_TIME);
    Items[UL_UP+1].Caption:='UL';
@@ -3053,17 +3060,18 @@
         5 : list.Columns.Items[i].Width:=50;
         6 : list.Columns.Items[i].Width:=70;
         7 : list.Columns.Items[i].Width:=40;
-        8 : list.Columns.Items[i].Width:=75;
-        9 : list.Columns.Items[i].Width:=40;
-       10 : list.Columns.Items[i].Width:=55;
-       11 : list.Columns.Items[i].Width:=30;
+        8 : list.Columns.Items[i].Width:=250;
+        9 : list.Columns.Items[i].Width:=75;
+       10 : list.Columns.Items[i].Width:=40;
+       11 : list.Columns.Items[i].Width:=55;
        12 : list.Columns.Items[i].Width:=30;
-       13 : list.Columns.Items[i].Width:=50;
+       13 : list.Columns.Items[i].Width:=30;
        14 : list.Columns.Items[i].Width:=50;
        15 : list.Columns.Items[i].Width:=50;
        16 : list.Columns.Items[i].Width:=50;
        17 : list.Columns.Items[i].Width:=50;
        18 : list.Columns.Items[i].Width:=50;
+       19 : list.Columns.Items[i].Width:=50;
        else break;
      end;
   inc(w,list.Columns.Items[i].Width);
@@ -3186,6 +3194,7 @@
  else if (list=list_users) and (index=UL_AVERAGE+1) then Result:=CompareDigit(str1,str2)
  else if (list=list_users) and (index=UL_SPEED+1) then Result:=CompareSpeed(str1,str2)
  else if (list=list_users) and (index=UL_IP+1) then Result:=CompareIP(str1,str2)
+ else if (list=list_users) and (index=UL_REMOTEHOST+1) then Result:=CompareRemoteHost(str1,str2)
  else if (list=list_users) and (index=UL_PORT+1) then Result:=CompareDigit(str1,str2)
  else if (list=list_users) and (index=UL_TIME+1) then Result:=CompareTime(str1,str2)
  else if (list=list_users) and (index=UL_UP+1) then Result:=CompareDigit(str1,str2)
@@ -4771,6 +4780,7 @@
  else if Sender=mnu_um_soft then n:=UL_SOFT+1
  else if Sender=mnu_um_speed then n:=UL_SPEED+1
  else if Sender=mnu_um_ip then n:=UL_IP+1
+ else if Sender=mnu_um_remotehost then n:=UL_REMOTEHOST+1
  else if Sender=mnu_um_port then n:=UL_PORT+1
  else if Sender=mnu_um_time then n:=UL_TIME+1
  else if Sender=mnu_um_up then n:=UL_UP+1
@@ -4821,6 +4831,7 @@
  mnu_um_soft.Checked:=isColumnVisible(list_users,UL_SOFT+1);
  mnu_um_speed.Checked:=isColumnVisible(list_users,UL_SPEED+1);
  mnu_um_ip.Checked:=isColumnVisible(list_users,UL_IP+1);
+ mnu_um_remotehost.Checked:=isColumnVisible(list_users,UL_REMOTEHOST+1);
  mnu_um_port.Checked:=isColumnVisible(list_users,UL_PORT+1);
  mnu_um_time.Checked:=isColumnVisible(list_users,UL_TIME+1);
  mnu_um_up.Checked:=isColumnVisible(list_users,UL_UP+1);
@@ -4915,6 +4926,21 @@
 procedure TSlavaNapWindow.edit_servers_autoreftimeChange(Sender: TObject);
 begin
   servreftime:=edit_servers_autoreftime.Value;
+end;
+
+function TSlavaNapWindow.CompareRemoteHost(str1,str2: String): Integer;
+ function ReverseString(const S: string): string;
+ var
+   I, L: Integer;
+ begin
+   SetLength(Result, Length(S));
+   L := Length(S);
+
+   for I := 0 to L - 1 do
+     Result[L - I] := S[I + 1];
+ end;
+begin
+ Result:=CompareStr(ReverseString(str1),ReverseString(str2));
 end;
 
 end.
diff --dos -urN 211126/mainform.dfm 211127/mainform.dfm
--- 211126/mainform.dfm	Mon Aug 11 14:29:40 2003
+++ 211127/mainform.dfm	Tue Aug 12 00:06:46 2003
@@ -1,6 +1,6 @@
 object SlavaNapWindow: TSlavaNapWindow
   Left = 259
-  Top = 109
+  Top = 175
   Width = 696
   Height = 480
   Caption = 'SlavaNapWindow'
@@ -1122,6 +1122,9 @@
                   Width = 74
                 end
                 item
+                  Caption = 'RemoteHost'
+                end
+                item
                   Alignment = taRightJustify
                   Caption = 'Port'
                   Width = 37
@@ -1305,7 +1308,7 @@
                 Width = 46
                 Height = 20
                 Style = csDropDownList
-                ItemHeight = 0
+                ItemHeight = 12
                 ParentShowHint = False
                 ShowHint = True
                 TabOrder = 6
@@ -1368,7 +1371,7 @@
                 Width = 92
                 Height = 20
                 Style = csDropDownList
-                ItemHeight = 0
+                ItemHeight = 12
                 ParentShowHint = False
                 ShowHint = True
                 TabOrder = 2
@@ -2067,7 +2070,7 @@
                 Width = 69
                 Height = 20
                 Style = csDropDownList
-                ItemHeight = 0
+                ItemHeight = 12
                 TabOrder = 1
               end
             end
@@ -4076,6 +4079,12 @@
     end
     object mnu_um_ip: TMenuItem
       Caption = 'ip'
+      OnClick = mnu_um_click
+      OnDrawItem = DrawPopupItem
+      OnMeasureItem = MeasurePopupItem
+    end
+    object mnu_um_remotehost: TMenuItem
+      Caption = 'リモートホストを表示'
       OnClick = mnu_um_click
       OnDrawItem = DrawPopupItem
       OnMeasureItem = MeasurePopupItem
diff --dos -urN 211126/vars.pas 211127/vars.pas
--- 211126/vars.pas	Sun Aug 10 23:09:16 2003
+++ 211127/vars.pas	Tue Aug 12 00:31:44 2003
@@ -158,7 +158,8 @@
  last_away_user: String;
  last_away_time: Cardinal;
  isHide: array [0..30] of Boolean;//list_users column visibility
- ul_gethost: Boolean;
+ ul_gethost_max_resolving_cnt: Integer;
+ whois_gethost: Boolean;
  // log
  log_to_file, log_console_data: Boolean;
  save_stats: Boolean;
diff --dos -urN 211126/handler.pas 211127/handler.pas
--- 211126/handler.pas	Mon Aug 11 03:23:14 2003
+++ 211127/handler.pas	Tue Aug 12 00:47:06 2003
@@ -22,7 +22,8 @@
 uses
  SysUtils, Classes, graphics, zlib, slavasplitter, slavapanel, winsock, windows,
  constants, users, servers, stypes, blcksock, synsock, localusers, registered,
- slavastrings, class_cmdlist, class_cmdexlist, mmsystem, local2global, mainform;
+ slavastrings, class_cmdlist, class_cmdexlist, mmsystem, local2global, mainform,
+ comctrls;
 
 function FindLocalUser(data: POnlineUser): TLocalUser; overload;
 function ProcessCommand(usr: TLocalUser; q: TQuery=queryNormal): Boolean;
@@ -44,12 +45,21 @@
 procedure Handler_ServerConnect(srv: TServer; timer: Boolean);
 procedure BanUser(ban,server: String;time: Integer; reason: String; write_all: Boolean);
 procedure AddReconnector(ip: String);
-procedure GetIpAddress( ip : string ; var Pbyte : array of Byte);
-function GetHost(ip : string) : string;
+function GetHostByIP(IP: String): String;
 
+type
+ TUserListReverseDNSThread = class(TThread)
+ protected
+ procedure Execute; override;
+ public
+   ip: Cardinal;
+   item: TListItem;
+   constructor Create(CreateSuspended: Boolean);
+ end;
 
 var
  gcmd: TNapCmd;
+ ResolvingCount: Integer; // ホスト名解決中のTUserListReverseDNSThreadの数
 
 implementation
 
@@ -5462,8 +5472,8 @@
  tmp_pos:=575;
  if i=1 then
  begin // complete whois reply
-   if ul_gethost then
-     str:=str+' '+IntToStr(user2^.total_down)+' '+IntToStr(user2^.total_up)+' '+decode_ip(user2^.ip)+'('+GetHost(decode_ip(user2^.ip))+') '
+   if whois_gethost then
+     str:=str+' '+IntToStr(user2^.total_down)+' '+IntToStr(user2^.total_up)+' '+decode_ip(user2^.ip)+'('+GetHostbyIP(decode_ip(user2^.ip))+') '
    else
      str:=str+' '+IntToStr(user2^.total_down)+' '+IntToStr(user2^.total_up)+' '+decode_ip(user2^.ip)+' ';
    l2:=FindLocalUser(user2);
@@ -10546,40 +10556,42 @@
  end;
 end;
 
-procedure GetIpAddress( ip : string ; var Pbyte : array of Byte);
-begin
-  PByte[0] := StrToInt(copy(ip,1,pos('.',ip)-1));
-  delete(ip,1,pos('.',ip));
-  PByte[1] := StrToInt(copy(ip,1,pos('.',ip)-1));
-  delete(ip,1,pos('.',ip));
-  PByte[2] := StrToInt(copy(ip,1,pos('.',ip)-1));
-  delete(ip,1,pos('.',ip));
-  PByte[3] := StrToInt(ip);
-end;
-
-function GetHost(ip : string) : string;
-var
-  PH : PHostEnt;
-  Ba : Array[0..3] of byte;
-  W : Word;
-  WSADATA : TWSADATA;
-begin
-  result := '';
-  if ip = '' then
-    exit;
-  GetIpAddress(ip,Ba);
-  W := MakeWord(1, 1);
-  WSAStartup(W, WSADATA);
-
-  PH := gethostbyaddr(@Ba,4,PF_INET);
-
-  if PH = nil then
-  begin
-    result := ip;
-    exit;
-  end;
-  result := string(ph^.h_name);
-  WSACleanup;
+function GetHostByIP(IP: String): String;
+var
+  ulIP: u_long;
+  phe: PHostEnt;
+  WSAStartError: Integer;
+  WSAData: TWSAData;
+begin
+  WSAStartError:=WSAStartUp($0101,WSAData);
+  Result:='';
+  ulIP:=inet_addr(PChar(IP));
+  phe:=gethostbyaddr(@ulIP,4,AF_INET);
+  if phe<>nil then
+    Result:=phe^.h_name;
+  WSACleanUp;
+end;
+
+constructor TUserListReverseDNSThread.Create(CreateSuspended: Boolean);
+begin
+  inherited Create(CreateSuspended);
+  Priority := tpIdle;
+end;
+
+procedure TUserListReverseDNSThread.Execute;
+var
+  hostname: String;
+begin
+  FreeOnTerminate:=True;
+  if Self.item=nil then exit;
+  if Self.ip=0 then exit;
+  while ResolvingCount>=ul_gethost_max_resolving_cnt do
+    Sleep(10);
+  Inc(ResolvingCount);
+    hostname:=GetHostByIP(decode_ip(Self.ip));
+    if item.SubItems.Count>UL_REMOTEHOST then
+      item.SubItems[UL_REMOTEHOST]:=hostname;
+  Dec(ResolvingCount);
 end;
 
 initialization