| 1 | /* Routines to handle smbtree output */ | 
|---|
| 2 |  | 
|---|
| 3 | /*:VRX */ | 
|---|
| 4 | _RefreshTree: | 
|---|
| 5 | say time()' _RefreshTree() started' | 
|---|
| 6 | FirstRun = 0 | 
|---|
| 7 | if VRIsValidObject("DT_STATUSBAR") then ok = VRSet("DT_STATUSBAR","Caption", "Refreshing network") | 
|---|
| 8 | ok = SysFileDelete(samba.!msg) | 
|---|
| 9 | parse var debuglevel .'='level | 
|---|
| 10 | if level = 0 then debuglevel = ' --debuglevel=1' | 
|---|
| 11 |  | 
|---|
| 12 | if UserCred   = 'USERCRED'   | UserCred = '' | UserCred = '--user=%' | UserCred = '--user=%%' then UserCred = '-N' | 
|---|
| 13 | if ShowHidden = 'SHOWHIDDEN' | ShowHidden = '' then ShowHidden = 0 | 
|---|
| 14 | if BroadCast = 1 then BroadCast = '-b'; else BroadCast = '' | 
|---|
| 15 |  | 
|---|
| 16 | say "  UserCred="UserCred | 
|---|
| 17 | samba.!serverlist = TempDir'smbtree.srvlst' | 
|---|
| 18 |  | 
|---|
| 19 | /* smbtree -b = Use broadcast instead of using the master browser | 
|---|
| 20 | smbtree -D = List only domains (workgroups) of tree | 
|---|
| 21 | smbtree -S = List domains(workgroups) and servers of */ | 
|---|
| 22 | say       '  detach 'samba.!smbtreeexe' 'BroadCast' -S 'UserCred' 'debuglevel' >'samba.!serverlist | 
|---|
| 23 | address cmd 'detach 'samba.!smbtreeexe' 'BroadCast' -S 'UserCred' 'debuglevel' >'samba.!serverlist | 
|---|
| 24 |  | 
|---|
| 25 | if level = 0 then debuglevel = ' --debuglevel=0' | 
|---|
| 26 |  | 
|---|
| 27 | /* strip username from caption */ | 
|---|
| 28 | UserContext = VRGet("CN_SMBTREE","Caption") | 
|---|
| 29 | UserContext = DelWord(UserContext,words(UserContext)) | 
|---|
| 30 |  | 
|---|
| 31 | if UserCred = '-N' then ok = VRSet("CN_SMBTREE","Caption",UserContext': Guest') | 
|---|
| 32 | else do | 
|---|
| 33 | parse var UserCred '--user='username'%'. | 
|---|
| 34 | ok = VRSet("CN_SMBTREE","Caption",UserContext": "username) | 
|---|
| 35 | end | 
|---|
| 36 |  | 
|---|
| 37 | if BroadCast = '-b' then BroadCast = 1; else BroadCast = 0 | 
|---|
| 38 | if UserCred  = '-N' then UserCred = '' | 
|---|
| 39 |  | 
|---|
| 40 | ok = VRMethod("CN_smbtree", "RemoveRecord", "ALL") | 
|---|
| 41 |  | 
|---|
| 42 | RefreshMode = "TREE" | 
|---|
| 43 | ok = VRSet("CN_smbtree","Enabled", 0) | 
|---|
| 44 | ok = VRset("TM_RefreshTreeDisplay","Enabled",1) | 
|---|
| 45 |  | 
|---|
| 46 | say time()' _RefreshTree() done' | 
|---|
| 47 | return | 
|---|
| 48 |  | 
|---|
| 49 | /*:VRX */ | 
|---|
| 50 | _RefreshTreeDisplay: | 
|---|
| 51 | say time()' _RefreshTreeDisplay() started' | 
|---|
| 52 |  | 
|---|
| 53 | stat = stream(samba.!serverlist,'c','open read') | 
|---|
| 54 | if stat <> "READY:" then do | 
|---|
| 55 | if VRIsValidObject("DT_STATUSBAR") then ok = VRSet("DT_STATUSBAR","Caption", VRGet("DT_STATUSBAR","Caption")||'.') | 
|---|
| 56 | return | 
|---|
| 57 | end | 
|---|
| 58 |  | 
|---|
| 59 | if UserCred = 'USERCRED' | UserCred = '' | UserCred = '--user=%' | UserCred = '--user=%%' then UserCred = '-N' | 
|---|
| 60 | if ShowHidden = 'SHOWHIDDEN' | ShowHidden = '' then ShowHidden = 0 | 
|---|
| 61 | if BroadCast = 1 then BroadCast = '-b'; else BroadCast = '' | 
|---|
| 62 |  | 
|---|
| 63 | if UserCred = '-N' then ok = VRSet("CN_SMBTREE","Caption","User context: Guest") | 
|---|
| 64 | else do | 
|---|
| 65 | parse var UserCred '--user='username'%'. | 
|---|
| 66 | ok = VRSet("CN_SMBTREE","Caption","User context: "username) | 
|---|
| 67 | end | 
|---|
| 68 |  | 
|---|
| 69 | ok = VRset("TM_RefreshTreeDisplay","Enabled",0) | 
|---|
| 70 | ok = VRSet("CN_smbtree", 'Enabled', 0 ) | 
|---|
| 71 |  | 
|---|
| 72 | ok = VRSet( "CN_smbtree", "Painting", 0  ) | 
|---|
| 73 | ok = VRMethod("CN_smbtree", "RemoveRecord", "ALL") | 
|---|
| 74 |  | 
|---|
| 75 | drop smbtree. | 
|---|
| 76 |  | 
|---|
| 77 | ok = file2stem(samba.!serverlist,"smbtreeline.") | 
|---|
| 78 |  | 
|---|
| 79 | do sl = 1 to smbtreeline.0 | 
|---|
| 80 | Header = c2x(left(smbtreeline.sl,3)) | 
|---|
| 81 | select | 
|---|
| 82 | when Header = "09095C" then nop /* share - obsolete, we only list domains and servers here */ | 
|---|
| 83 | when Header = "095C5C" then do  /* machine */ | 
|---|
| 84 | smbtreeline.sl = strip(smbtreeline.sl,,'09'x) | 
|---|
| 85 | parse var smbtreeline.sl '\\'machine '0909'x comment | 
|---|
| 86 | machine = strip(machine) | 
|---|
| 87 | comment = strip(comment) | 
|---|
| 88 | if VRGet("CN_smbtree","View") = "IconTree" then parent = smbtree.!workgroup; else parent = "" | 
|---|
| 89 | /* We create any machine as sleeping initially */ | 
|---|
| 90 | smbtree.!machine = _AddSleepingMachine(machine,comment,parent) | 
|---|
| 91 |  | 
|---|
| 92 | ok = VRSet( "CN_smbtree", "Painting", 1  ) | 
|---|
| 93 | ok = VRSet( "CN_smbtree", "Painting", 0  ) | 
|---|
| 94 |  | 
|---|
| 95 | if VRGet("CN_smbtree","View") <> "Detail" then do | 
|---|
| 96 | /* Tree view */ | 
|---|
| 97 | call _RefreshShares | 
|---|
| 98 | end | 
|---|
| 99 | else do /* Fill records for details view */ | 
|---|
| 100 | ok = VRSet("Main", 'Pointer', 'Wait' ) | 
|---|
| 101 | /* Get NMBLookup Status for machine */ | 
|---|
| 102 | NMBStatus = _GetMachineNMBSTatus(machine) | 
|---|
| 103 | parse var NMBStatus IPStr'|'MAC '|' Roles; drop NMBStatus | 
|---|
| 104 | if pos("PDC",Roles) > 0 then ok = VRMethod( "CN_smbtree", "SetRecordAttr", smbtree.!machine, "Icon","#63:PMWP.DLL") | 
|---|
| 105 | ok = VRMethod( "CN_smbtree", "SetFieldData", smbtree.!machine, IPFH, IPStr,MBFH, Roles, MacFH,MAC) | 
|---|
| 106 |  | 
|---|
| 107 | /* FIXME: Possibly obsolete */ | 
|---|
| 108 | parse var IPStr MachineIP ',' . | 
|---|
| 109 | if strip(MachineIP) = "" then MachineIP = machine | 
|---|
| 110 |  | 
|---|
| 111 | ok = VRSet("Main", 'Pointer', '<default>' ) | 
|---|
| 112 |  | 
|---|
| 113 | /* Find out OS, version */ | 
|---|
| 114 | say     '  'samba.!smbclientexe' -L "'machine'" 'UserCred' 'debuglevel' 2>'samba.!msg' 1>NUL' | 
|---|
| 115 | address cmd samba.!smbclientexe' -L "'machine'" 'UserCred' 'debuglevel' 2>'samba.!msg' 1>NUL' | 
|---|
| 116 | smbline = linein(samba.!msg) | 
|---|
| 117 | ok = stream(samba.!msg,'c','close') | 
|---|
| 118 | parse var smbline "Domain=["WorkGroup"] OS=["OS"] Server=["Version"]"Rest | 
|---|
| 119 | ok = VRMethod( "CN_smbtree", "SetFieldData", smbtree.!machine, OSFH, OS, VersionFH, Version, WorkgroupFH, WorkGroup) | 
|---|
| 120 | end | 
|---|
| 121 | end | 
|---|
| 122 | when smbtreeline.sl = "" then nop /* skip empty lines */ | 
|---|
| 123 | otherwise do /* possible new workgroup */ | 
|---|
| 124 | say '  Possible workgroup: "'smbtreeline.sl'"' | 
|---|
| 125 | ThrowMsg = 0 | 
|---|
| 126 | /* Do some checks to be sure */ | 
|---|
| 127 | select | 
|---|
| 128 | when pos("RECEIVING",translate(smbtreeline.sl)) > 0 then ThrowMsg = 1 | 
|---|
| 129 | when pos("NT_STATUS",translate(smbtreeline.sl)) > 0 then ThrowMsg = 1 | 
|---|
| 130 | when pos(" ", smbtreeline.sl) > 0 then ThrowMsg = 1 | 
|---|
| 131 | when pos("=", smbtreeline.sl) > 0 then ThrowMsg = 1 | 
|---|
| 132 | when pos(":", smbtreeline.sl) > 0 then ThrowMsg = 1 | 
|---|
| 133 | when pos("%", smbtreeline.sl) > 0 then ThrowMsg = 1 | 
|---|
| 134 | otherwise do /* it is really a new workgroup */ | 
|---|
| 135 | if VRGet("CN_smbtree","View") = "IconTree" then do | 
|---|
| 136 | say "Checks passed, "smbtreeline.sl" is a workgroup!" | 
|---|
| 137 | smbtree.!workgroup = _AddWorkGroup(smbtreeline.sl) | 
|---|
| 138 | CurWG = smbtreeline.sl | 
|---|
| 139 | end | 
|---|
| 140 | end | 
|---|
| 141 | end | 
|---|
| 142 | if ThrowMsg = 1 then do | 
|---|
| 143 | call beep 2400, 500 | 
|---|
| 144 | ThrowMsg = 0 | 
|---|
| 145 | Msg.Type = "W" | 
|---|
| 146 | Msg.Text = smbtreeline.sl | 
|---|
| 147 | call _ShowMsg | 
|---|
| 148 | end | 
|---|
| 149 | end | 
|---|
| 150 | end | 
|---|
| 151 | end | 
|---|
| 152 |  | 
|---|
| 153 | ok = VRSet( "CN_smbtree", "Painting", 1  ) | 
|---|
| 154 |  | 
|---|
| 155 | /*  ok = VRSet("Main", 'Pointer', '<default>' ) */ | 
|---|
| 156 | ok = VRSet("CN_smbtree","Enabled", 1) | 
|---|
| 157 | ok = VRSet("TM_Throbber","Enabled", 0) | 
|---|
| 158 | ok = VRSet("Pict_Throbber","Visible", 0) | 
|---|
| 159 | say time()' _RefreshTreeDisplay() done' | 
|---|
| 160 | return | 
|---|
| 161 |  | 
|---|
| 162 | /*:VRX         _RefreshShares */ | 
|---|
| 163 | _RefreshShares: | 
|---|
| 164 | say time()' _RefreshShares() started' | 
|---|
| 165 |  | 
|---|
| 166 | smbmachine = TempDir||"smbmachine."||machine | 
|---|
| 167 | MaxSmbClient = 32 /* Do not run more than MaxSmbClient instances of smbclient.exe at the same time */ | 
|---|
| 168 |  | 
|---|
| 169 | Defer = 1 | 
|---|
| 170 | do while Defer = 1 | 
|---|
| 171 | SmbCltCount = 0 | 
|---|
| 172 | ok = PRProcessList(proc) | 
|---|
| 173 |  | 
|---|
| 174 | do I = 1 to proc.0 | 
|---|
| 175 | CurProc = VRParseFileName(proc.i.name,'NE') | 
|---|
| 176 | if CurProc = "SMBCLIENT.EXE" then SmbCltCount = SmbCltCount + 1 | 
|---|
| 177 | end | 
|---|
| 178 | say '  'SmbCltCount' instance(s) of 'samba.!smbclientexe' is/are running.' | 
|---|
| 179 | if SmbCltCount >= MaxSmbClient then do | 
|---|
| 180 | say "  Waiting until at least "SmbCltCount-MaxSmbClient+1" instance(s) of smbclient.exe terminate(s)." | 
|---|
| 181 | ok = SysSleep(1) | 
|---|
| 182 | end | 
|---|
| 183 | else Defer = 0 | 
|---|
| 184 | end | 
|---|
| 185 |  | 
|---|
| 186 | if UserCred   = 'USERCRED'   | UserCred = '' | UserCred = '--user=%' | UserCred = '--user=%%' then UserCred = '-N' | 
|---|
| 187 |  | 
|---|
| 188 | /* We have to remove the double % for smbclient.exe - not entirely clear why */ | 
|---|
| 189 | OldUserCred = "" | 
|---|
| 190 | if pos('%%',UserCred) > 0 & pos("4OS2", value("COMSPEC",,"OS2ENVIRONMENT")) = 0  then do | 
|---|
| 191 | OldUserCred = UserCred | 
|---|
| 192 | parse var UserCred '--user='username'%%'password | 
|---|
| 193 | UserCred = '--user='username'%'password | 
|---|
| 194 | say "  Strip double %%!!!" | 
|---|
| 195 | end | 
|---|
| 196 |  | 
|---|
| 197 | say       '  detach 'samba.!smbclientexe' -L "'machine'" 'UserCred' 'debuglevel' 2>'smbmachine' 1>&2' | 
|---|
| 198 | address cmd 'detach 'samba.!smbclientexe' -L "'machine'" 'UserCred' 'debuglevel' 2>'smbmachine' 1>&2' | 
|---|
| 199 |  | 
|---|
| 200 | if UserCred = '-N' then ok = VRSet("CN_SMBTREE","Caption","User context: Guest") | 
|---|
| 201 | else do | 
|---|
| 202 | parse var UserCred '--user='username'%'. | 
|---|
| 203 | ok = VRSet("CN_SMBTREE","Caption","User context: "username) | 
|---|
| 204 | end | 
|---|
| 205 |  | 
|---|
| 206 | if OldUserCred <> "" then do | 
|---|
| 207 | UserCred = OldUserCred | 
|---|
| 208 | OldUserCred = "" | 
|---|
| 209 | say "  Restore double %%!!!" | 
|---|
| 210 | end | 
|---|
| 211 |  | 
|---|
| 212 | if UserCred = '-N' then UserCred = '' | 
|---|
| 213 |  | 
|---|
| 214 | RefreshMode = "SHARE" | 
|---|
| 215 |  | 
|---|
| 216 | ok = VRSet("CN_smbtree","Enabled", 0) | 
|---|
| 217 | ok = VRset("TM_RefreshTreeDisplay","Enabled",1) | 
|---|
| 218 | say time()' _RefreshShares() done' | 
|---|
| 219 | return | 
|---|
| 220 |  | 
|---|
| 221 | /*:VRX         _AddSharesDisplay | 
|---|
| 222 | */ | 
|---|
| 223 | _AddSharesDisplay: /* New get shares code - uses smbclient output and is much faster */ | 
|---|
| 224 | say time()' _AddSharesDisplay() started' | 
|---|
| 225 |  | 
|---|
| 226 | ok = SysFileTree(Tempdir||'smbmachine.*',smbmachine.,'FO') | 
|---|
| 227 | if smbmachine.0 = 0 then do /* we are done, no more files around, cleanup, disable Timer and exit */ | 
|---|
| 228 | RefreshMode = "" | 
|---|
| 229 | ok = VRset("TM_RefreshTreeDisplay","Enabled", 0) | 
|---|
| 230 | ok = VRSet("TM_RefreshTreeDisplay","Delay", 1000) | 
|---|
| 231 | ok = VRSet("CN_smbtree","Enabled", 1) | 
|---|
| 232 | if DoLMHosts = 1 then do | 
|---|
| 233 | call _LMHostsRead | 
|---|
| 234 | call _LMHostsUpdate | 
|---|
| 235 | end | 
|---|
| 236 | ok = VRSet("CN_smbtree", "Painting", 0 ) | 
|---|
| 237 | ok = VRSet("CN_smbtree", "Painting", 1 ) | 
|---|
| 238 | say time()' _AddSharesDisplay() completed' | 
|---|
| 239 | return /* exit here */ | 
|---|
| 240 | end | 
|---|
| 241 | else do | 
|---|
| 242 | say '  'smbmachine.0' file(s) to process.' | 
|---|
| 243 | if smbmachine.0 = 1 then ok = VRSet("TM_RefreshTreeDisplay", "Delay", VRGet("TM_RefreshTreeDisplay", "Delay") * 2) | 
|---|
| 244 | end | 
|---|
| 245 |  | 
|---|
| 246 | if UserCred   = 'USERCRED'   | UserCred = '' | UserCred = '--user=%' | UserCred = '--user=%%' then UserCred = '-N' | 
|---|
| 247 | if ShowHidden = 'SHOWHIDDEN' | ShowHidden = '' then ShowHidden = 0 | 
|---|
| 248 |  | 
|---|
| 249 | do I = 1 to smbmachine.0 | 
|---|
| 250 | call charout , '  Going for "'smbmachine.I'", got ' | 
|---|
| 251 | if VRIsValidObject("DT_STATUSBAR") then ok = VRSet("DT_STATUSBAR","Caption", VRGet("DT_STATUSBAR","Caption")||'.') | 
|---|
| 252 | stat = stream(smbmachine.I,'c','open read') | 
|---|
| 253 | say '  Try to open "'smbmachine.I'" for reading: "'stat'"' | 
|---|
| 254 | if stat = "READY:" & smbmachine.0 = 1 then do /* We just found out we are processing the last machine */ | 
|---|
| 255 | ok = VRSet("TM_RefreshTreeDisplay","Delay", 1000) | 
|---|
| 256 | end | 
|---|
| 257 | infoline = "" | 
|---|
| 258 | if stat = "READY:" then do /* we found a readable output file */ | 
|---|
| 259 | OneWorkGroupOnly = 0 | 
|---|
| 260 | GuestRetry = 0 | 
|---|
| 261 |  | 
|---|
| 262 | Machine = substr(smbmachine.I,pos('.',smbmachine.I)+1) | 
|---|
| 263 | if right(Machine,4) = '$rt$' then do | 
|---|
| 264 | Machine = left(Machine, length(Machine) - 4) | 
|---|
| 265 | GuestRetry = 1 | 
|---|
| 266 | end | 
|---|
| 267 |  | 
|---|
| 268 |  | 
|---|
| 269 | smbtree.!machine = _GetMachinehandle(Machine) | 
|---|
| 270 |  | 
|---|
| 271 | if smbtree.!machine = "" then do /* invalid (old) file */ | 
|---|
| 272 | say time()' _AddSharesDisplay() exit with Invalid file found (no corresponding machine)' | 
|---|
| 273 | ok = stream(smbmachine.I,'c','close') | 
|---|
| 274 | ok = SysFileDelete(smbmachine.I) | 
|---|
| 275 | iterate | 
|---|
| 276 | end | 
|---|
| 277 | line = linein(smbmachine.I) /* PID line */ | 
|---|
| 278 | line = linein(smbmachine.I) | 
|---|
| 279 | if pos('creating lame', line) > 0 then do | 
|---|
| 280 | line = linein(smbmachine.I) | 
|---|
| 281 | line = linein(smbmachine.I) | 
|---|
| 282 | end | 
|---|
| 283 | if pos('Server=[', line) > 0 then do | 
|---|
| 284 | infoline = linein(smbmachine.I) | 
|---|
| 285 | parse var infoline "Domain=["WorkGroup"] OS=["OS"] Server=["Server"]"Rest | 
|---|
| 286 | ok = VRMethod( "CN_smbtree", "SetFieldData", smbtree.!machine, OSFH, OS, VersionFH, Server) | 
|---|
| 287 | line = linein(smbmachine.I) | 
|---|
| 288 | end | 
|---|
| 289 | /* Filter possible debug messages */ | 
|---|
| 290 | do while(pos("TDB(",translate(line)) > 0) | (pos("%",line) > 0) | (pos("=",line) > 0) | 
|---|
| 291 | say '  Skip "'line'"' | 
|---|
| 292 | line = linein(smbmachine.I) | 
|---|
| 293 | end | 
|---|
| 294 | say '  Message "'line'"' | 
|---|
| 295 |  | 
|---|
| 296 | ok = VRMethod('CN_smbtree', 'SetRecordAttr', smbtree.!machine, 'UserData', "SERVER|"||strip(line)) | 
|---|
| 297 |  | 
|---|
| 298 | if pos("FAIL", translate(line)) > 0 then do /* we see an error message - the term "FAIL" seems to be common to all */ | 
|---|
| 299 | say time()' _AddSharesDisplay() exit with "'line'"' | 
|---|
| 300 | ok = stream(smbmachine.I,'c','close') | 
|---|
| 301 | ok = SysFileDelete(smbmachine.I) | 
|---|
| 302 | /* Try with guest account once */ | 
|---|
| 303 |  | 
|---|
| 304 | if GuestRetry = 0 & UserCred <> '-N' then do | 
|---|
| 305 | say       '  detach 'samba.!smbclientexe' -L "'machine'" -N 'debuglevel' 2>'smbmachine.I'$rt$ 1>&2' | 
|---|
| 306 | address cmd 'detach 'samba.!smbclientexe' -L "'machine'" -N 'debuglevel' 2>'smbmachine.I'$rt$ 1>&2' | 
|---|
| 307 | end | 
|---|
| 308 |  | 
|---|
| 309 | iterate | 
|---|
| 310 | end | 
|---|
| 311 |  | 
|---|
| 312 | retries = 0 | 
|---|
| 313 | do while(left(line,1) <> '09'x) | 
|---|
| 314 | line = linein(smbmachine.I) | 
|---|
| 315 | retries = retries + 1 | 
|---|
| 316 | say '  Skip 'retries' "'line'"' | 
|---|
| 317 | if retries >=10 then do /* No valid output - error */ | 
|---|
| 318 | say time()' _AddSharesDisplay() exit with invalid output error' | 
|---|
| 319 | ok = stream(smbmachine.I,'c','close') | 
|---|
| 320 | ok = SysFileDelete(smbmachine.I) | 
|---|
| 321 | leave | 
|---|
| 322 | end | 
|---|
| 323 | end | 
|---|
| 324 | if retries >=10 then iterate | 
|---|
| 325 |  | 
|---|
| 326 | /* Skip header */ | 
|---|
| 327 | line = linein(smbmachine.I) | 
|---|
| 328 | line = linein(smbmachine.I) | 
|---|
| 329 |  | 
|---|
| 330 | if translate(left(strip(line),5)) = "ERROR" then ok = VRMethod('CN_smbtree', 'SetRecordAttr', smbtree.!machine, 'UserData', "SERVER|"||strip(line)) | 
|---|
| 331 |  | 
|---|
| 332 | do while(left(line,1) = '09'x) /* Share loop */ | 
|---|
| 333 | share   = strip(substr(line,2,16)) | 
|---|
| 334 | type    = translate(strip(substr(line,17,10))) | 
|---|
| 335 | comment = strip(substr(line,27,)) | 
|---|
| 336 |  | 
|---|
| 337 | select | 
|---|
| 338 | when type = "DISK"    then res = '#64:PMWP.DLL' | 
|---|
| 339 | when type = "PRINTER" then res = '#65:PMWP.DLL' | 
|---|
| 340 | when type = "IPC"     then res = '#59:PMWP.DLL' | 
|---|
| 341 | when type = "DEVICE"  then res = '#84:PMWP.DLL' /* There might be better ones around */ | 
|---|
| 342 | otherwise res = '' | 
|---|
| 343 | end | 
|---|
| 344 |  | 
|---|
| 345 | /* Now the machine receives the wakeup icon */ | 
|---|
| 346 | ok = VRMethod('CN_smbtree', 'SetRecordAttr', smbtree.!machine, 'Icon', "#35:PMWP.DLL") | 
|---|
| 347 |  | 
|---|
| 348 | parent = smbtree.!machine | 
|---|
| 349 | smbtree.!share = VRMethod( "CN_smbtree", "AddRecord",parent,, share||'0D0A'x||comment, res) | 
|---|
| 350 | ok = VRMethod( "CN_smbtree", "SetRecordAttr", smbtree.!share, "ReadOnly", 1, 'UserData', type"|") | 
|---|
| 351 | if pos("$", share) > 0 then ok = VRMethod( "CN_smbtree", "SetRecordAttr", smbtree.!share, "Visible", ShowHidden) | 
|---|
| 352 |  | 
|---|
| 353 | /* get next share */ | 
|---|
| 354 | line = linein(smbmachine.I) | 
|---|
| 355 | end /* Share loop */ | 
|---|
| 356 |  | 
|---|
| 357 | do until left(line,10) = '09'x||'Workgroup' | lines(smbmachine.I) = 0 | 
|---|
| 358 | line = linein(smbmachine.I) | 
|---|
| 359 | end | 
|---|
| 360 | line = linein(smbmachine.I) /* this should be the -------- string */ | 
|---|
| 361 | /* Reading FIRST workgroup and master - eventually both empty */ | 
|---|
| 362 | line = linein(smbmachine.I) | 
|---|
| 363 |  | 
|---|
| 364 | /* Multiple workgroups? */ | 
|---|
| 365 | if lines(smbmachine.I) = 0 then OneWorkGroupOnly = 1 | 
|---|
| 366 | else OneWorkGroupOnly = 0 | 
|---|
| 367 | say "  OneWorkGroupOnly = "OneWorkGroupOnly | 
|---|
| 368 |  | 
|---|
| 369 | parse var line '09'x workgroup master | 
|---|
| 370 | master = strip(master) | 
|---|
| 371 |  | 
|---|
| 372 | /* we use this to set the workgroup for manually added servers - if there is ONLY ONE workgroup */ | 
|---|
| 373 | if workgroup <> "" & OneWorkGroupOnly = 1 then do | 
|---|
| 374 | wgh = _GetMachinehandle(workgroup) | 
|---|
| 375 | if wgh = "" then do /* The machine appears to be in a new workgroup - add it as well */ | 
|---|
| 376 | /* NOTE: This should be obsolete now because the list of available     */ | 
|---|
| 377 | /*       workgroups should always have been updated before we get here */ | 
|---|
| 378 | wgh = _AddWorkGroup(workgroup) | 
|---|
| 379 | end | 
|---|
| 380 | /* we only do this for machines with empty parent (=workgroup) handle */ | 
|---|
| 381 | /* IF there is only one workgroup */ | 
|---|
| 382 | if wgh <> "" & VRMethod('CN_smbtree', 'GetRecordAttr', smbtree.!machine, 'Parent') = "" then do | 
|---|
| 383 | ok = VRMethod('CN_smbtree', 'SetRecordAttr', smbtree.!machine, 'Parent', wgh) | 
|---|
| 384 | end | 
|---|
| 385 | end | 
|---|
| 386 | else do | 
|---|
| 387 | if workgroup <> "" then do | 
|---|
| 388 | /* There are multiple workgroups, we need additional */ | 
|---|
| 389 | /* measures to find out which is our workgroup       */ | 
|---|
| 390 | if infoline <> "" then do | 
|---|
| 391 | say     '  'samba.!smbclientexe' -L "'Machine'" -N 'debuglevel' 2>'samba.!msg' 1>NUL' | 
|---|
| 392 | address cmd samba.!smbclientexe' -L "'Machine'" -N 'debuglevel' 2>'samba.!msg' 1>NUL' | 
|---|
| 393 | infoline = linein(samba.!msg) | 
|---|
| 394 |  | 
|---|
| 395 | if word(infoline,1) = "creating" then do /* upcase tables are missing */ | 
|---|
| 396 | say "Missing upcase tables detected!" | 
|---|
| 397 | infoline = linein(samba.!msg) | 
|---|
| 398 | infoline = linein(samba.!msg) | 
|---|
| 399 | end | 
|---|
| 400 | IF options.!debug == 1 THEN say '  Response = "'Infoline'"' | 
|---|
| 401 | ok = stream(samba.!msg,'c','close') | 
|---|
| 402 | ok = SysFileDelete(samba.!msg) | 
|---|
| 403 | end | 
|---|
| 404 |  | 
|---|
| 405 | parse var infoline "Domain=["WorkGroup"] OS=["OS"] Server=["Server"]"Rest | 
|---|
| 406 |  | 
|---|
| 407 | wgh = _GetMachinehandle(workgroup) | 
|---|
| 408 | if wgh <> "" & VRMethod('CN_smbtree', 'GetRecordAttr', smbtree.!machine, 'Parent') = "" then do | 
|---|
| 409 | ok = VRMethod('CN_smbtree', 'SetRecordAttr', smbtree.!machine, 'Parent', wgh) | 
|---|
| 410 | end | 
|---|
| 411 | end | 
|---|
| 412 | else do | 
|---|
| 413 | /* The machine does not allow browsing and does not report a workgroup here */ | 
|---|
| 414 | say '  "'Machine'" does not allow browsing.' | 
|---|
| 415 | end | 
|---|
| 416 | end | 
|---|
| 417 |  | 
|---|
| 418 | ok = VRSet("Main", 'Pointer', 'Wait' ) | 
|---|
| 419 |  | 
|---|
| 420 | /* Get NMBLookup Status for machine */ | 
|---|
| 421 | NMBStatus = _GetMachineNMBSTatus(machine) | 
|---|
| 422 | parse var NMBStatus IPStr'|'MAC '|' Roles; drop NMBStatus | 
|---|
| 423 | if pos("PDC",Roles) > 0 then ok = VRMethod( "CN_smbtree", "SetRecordAttr", smbtree.!machine, "Icon","#63:PMWP.DLL") | 
|---|
| 424 | ok = VRMethod( "CN_smbtree", "SetFieldData", smbtree.!machine, IPFH, IPStr,MBFH, Roles, MacFH,MAC) | 
|---|
| 425 |  | 
|---|
| 426 | ok = VRSet("Main", 'Pointer', '<default>' ) | 
|---|
| 427 |  | 
|---|
| 428 | say time()' _AddSharesDisplay() success and cleanup' | 
|---|
| 429 | ok = stream(smbmachine.I,'c','close') | 
|---|
| 430 | ok = SysFileDelete(smbmachine.I) | 
|---|
| 431 | if ok <> 0 then say '  Failure 'ok' deleting "'smbmachine.I'"!' | 
|---|
| 432 | end | 
|---|
| 433 | end | 
|---|
| 434 |  | 
|---|
| 435 | if UserCred = '-N' then UserCred = '' | 
|---|
| 436 |  | 
|---|
| 437 | if VRIsValidObject("DT_STATUSBAR") then ok = VRSet("DT_STATUSBAR","Caption", "Ready.") | 
|---|
| 438 | say time()' _AddSharesDisplay() loop end' | 
|---|
| 439 | return | 
|---|
| 440 |  | 
|---|
| 441 | /*:VRX         _GetMachinehandle | 
|---|
| 442 | */ | 
|---|
| 443 |  | 
|---|
| 444 | _GetMachinehandle: procedure /* get recordhandle by machine name (also works for workgroups) */ | 
|---|
| 445 | Machine = translate(arg(1)) | 
|---|
| 446 | say '  _GetMachineHandle("'Machine'") started.' | 
|---|
| 447 | ok = VRMethod("CN_smbtree", "GetRecordList", "All", rh.) | 
|---|
| 448 | match = 0 | 
|---|
| 449 |  | 
|---|
| 450 | do I = 1 to rh.0 | 
|---|
| 451 | ResName  = translate(VRMethod("CN_smbtree","GetRecordAttr",rh.I,"Caption")) | 
|---|
| 452 |  | 
|---|
| 453 | parse var ResName  ResName '0D0A'x . | 
|---|
| 454 | ResName = strip(ResName) | 
|---|
| 455 |  | 
|---|
| 456 | if Machine = ResName then do /* we got a matching name */ | 
|---|
| 457 | match = 1 | 
|---|
| 458 | leave | 
|---|
| 459 | end | 
|---|
| 460 | end | 
|---|
| 461 | if match = 0 then rh.I = "" /* return an empty handle, if there was no match */ | 
|---|
| 462 | say '  _GetMachineHandle("'Machine'") done, handle = "'rh.I'"' | 
|---|
| 463 | return rh.I | 
|---|
| 464 |  | 
|---|
| 465 | /*:VRX         _RefreshWorkgroups | 
|---|
| 466 | */ | 
|---|
| 467 | _RefreshWorkgroups: | 
|---|
| 468 | say time()' _RefreshWorkgroups() started' | 
|---|
| 469 | if UserCred   = 'USERCRED'   | UserCred = '' | UserCred = '--user=%' | UserCred = '--user=%%' then UserCred = '-N' | 
|---|
| 470 | if BroadCast = 1 then BroadCast = '-b'; else BroadCast = '' | 
|---|
| 471 |  | 
|---|
| 472 | call VRSet VRWindow(), 'Pointer', 'Wait' | 
|---|
| 473 |  | 
|---|
| 474 | /* smbtree -b = Use broadcast instead of using the master browser | 
|---|
| 475 | smbtree -D = List only domains (workgroups) of tree | 
|---|
| 476 | smbtree -S = List domains(workgroups) and servers of */ | 
|---|
| 477 | say       '  detach 'samba.!smbtreeexe' 'BroadCast' -D 'UserCred' 'debuglevel' >'samba.!msg | 
|---|
| 478 | address cmd 'detach 'samba.!smbtreeexe' 'BroadCast' -D 'UserCred' 'debuglevel' >'samba.!msg | 
|---|
| 479 |  | 
|---|
| 480 | if VRIsValidObject("DT_STATUSBAR") then ok = VRSet("DT_STATUSBAR","Caption","Enumerating workgroups") | 
|---|
| 481 | do while stream(samba.!msg,'c','open read') <> "READY:" | 
|---|
| 482 | ok = SysSleep(1) | 
|---|
| 483 | if VRIsValidObject("DT_STATUSBAR") then ok = VRSet("DT_STATUSBAR","Caption", VRGet("DT_STATUSBAR","Caption")||'.') | 
|---|
| 484 | end | 
|---|
| 485 | call VRSet VRWindow(), 'Pointer', '<default>' | 
|---|
| 486 |  | 
|---|
| 487 | if BroadCast = '-b' then BroadCast = 1; else BroadCast = 0 | 
|---|
| 488 | if UserCred = '-N' then UserCred = '' | 
|---|
| 489 |  | 
|---|
| 490 | ok = File2Stem(samba.!msg,"workgroups.") | 
|---|
| 491 | do I = 1 to workgroups.0 | 
|---|
| 492 | workgroup = translate(workgroups.I) | 
|---|
| 493 | if pos("RECEIVING",workgroup) > 0 | pos("TDB(",workgroup) > 0 then iterate /* We ignore errors here */ | 
|---|
| 494 | wgh = _GetMachinehandle(workgroup) | 
|---|
| 495 | if wgh = "" then wgh = _AddWorkGroup(workgroup) /* A new workgroup was found -- add it */ | 
|---|
| 496 | end | 
|---|
| 497 | say time()' _RefreshWorkgroups() done' | 
|---|
| 498 | return | 
|---|
| 499 |  | 
|---|
| 500 | /*:VRX         _AddWorkgroup | 
|---|
| 501 | */ | 
|---|
| 502 | _AddWorkGroup: procedure expose WorkGroupFH | 
|---|
| 503 | workgroup = arg(1) | 
|---|
| 504 | say '  _AddWorkGroup("'workgroup'") started.' | 
|---|
| 505 | wgh= VRMethod( "CN_smbtree", "AddRecord",,, workgroup,"#62:PMWP.DLL") | 
|---|
| 506 | ok = VRMethod( "CN_smbtree", "SetFieldData",  wgh, WorkGroupFH, workgroup) | 
|---|
| 507 | ok = VRMethod( "CN_smbtree", "SetRecordAttr", wgh, "Collapsed", 0) | 
|---|
| 508 | ok = VRMethod( "CN_smbtree", "SetRecordAttr", wgh, "ReadOnly", 1) | 
|---|
| 509 | ok = VRMethod( "CN_smbtree", 'SetRecordAttr', wgh, "UserData", "WORKGROUP|") | 
|---|
| 510 | say '  _AddWorkGroup("'workgroup'") done.' | 
|---|
| 511 | return wgh | 
|---|
| 512 |  | 
|---|
| 513 | /*:VRX         _AddSleepingMachine | 
|---|
| 514 | */ | 
|---|
| 515 | _AddSleepingMachine: procedure expose WorkGroupFH NBFH CommentFH | 
|---|
| 516 | machine = arg(1) | 
|---|
| 517 | comment = arg(2) | 
|---|
| 518 | parent  = arg(3) | 
|---|
| 519 | mh = VRMethod( "CN_smbtree", "AddRecord",parent,, machine||'0D0A'x||comment) | 
|---|
| 520 | ok = VRMethod( "CN_smbtree", "SetFieldData",  mh, NBFH, machine, CommentFH, comment) | 
|---|
| 521 | ok = VRMethod( "CN_smbtree", "SetRecordAttr", mh, "Icon","#61:PMWP.DLL") | 
|---|
| 522 | ok = VRMethod( "CN_smbtree", "SetRecordAttr", mh, "ReadOnly", 1) | 
|---|
| 523 | ok = VRMethod( "CN_smbtree", "SetRecordAttr", mh, "Collapsed", 1) | 
|---|
| 524 | ok = VRMethod( "CN_smbtree", 'SetRecordAttr', mh, "UserData", "SERVER|") | 
|---|
| 525 | if parent <> "" then do | 
|---|
| 526 | WGName  = translate(VRMethod("CN_smbtree","GetRecordAttr",parent,"Caption")) | 
|---|
| 527 | parse var WGName  WGName '0D0A'x . | 
|---|
| 528 | ok = VRMethod( "CN_smbtree", "SetFieldData",  mh, WorkgroupFH, strip(WGName)) | 
|---|
| 529 | end | 
|---|
| 530 | return mh | 
|---|
| 531 |  | 
|---|
| 532 | /*:VRX         _GetMachineIP | 
|---|
| 533 | */ | 
|---|
| 534 | _GetMachineIP: procedure expose debuglevel samba. | 
|---|
| 535 | say time()' _GetMachineIP() started' | 
|---|
| 536 | /* Get all IP addresses of the machine */ | 
|---|
| 537 | machine = arg(1) | 
|---|
| 538 | call VRSet VRWindow(), 'Pointer', 'Wait' | 
|---|
| 539 | say       '  detach 'samba.!nmblookupexe' 'machine' 'debuglevel' >'samba.!msg | 
|---|
| 540 | address cmd 'detach 'samba.!nmblookupexe' 'machine' 'debuglevel' >'samba.!msg | 
|---|
| 541 |  | 
|---|
| 542 | if VRIsValidObject("DT_STATUSBAR") then ok = VRSet("DT_STATUSBAR","Caption","Obtaining IP from "machine) | 
|---|
| 543 | do while stream(samba.!msg,'c','open read') <> "READY:" | 
|---|
| 544 | ok = SysSleep(0.33) | 
|---|
| 545 | if VRIsValidObject("DT_STATUSBAR") then ok = VRSet("DT_STATUSBAR","Caption", VRGet("DT_STATUSBAR","Caption")||'.') | 
|---|
| 546 | end | 
|---|
| 547 | call VRSet VRWindow(), 'Pointer', '<default>' | 
|---|
| 548 |  | 
|---|
| 549 | ok = file2stem(samba.!msg,"nmblookup.") | 
|---|
| 550 | ipstr = ""; ip = "" | 
|---|
| 551 | do i = 1 to nmblookup.0 | 
|---|
| 552 | if pos(strip(machine)'<',nmblookup.i) = 0 then iterate | 
|---|
| 553 | parse var nmblookup.i ip . | 
|---|
| 554 | if pos(strip(ip), ipstr) = 0 then ipstr = ipstr||ip',' | 
|---|
| 555 | end | 
|---|
| 556 | ipstr = strip(ipstr,,',') | 
|---|
| 557 | say time()' _GetMachineIP() done' | 
|---|
| 558 | return IpStr | 
|---|
| 559 |  | 
|---|
| 560 | /*:VRX         _GetMachineRole | 
|---|
| 561 | */ | 
|---|
| 562 | _GetMachineMACRoles: procedure expose debuglevel samba. | 
|---|
| 563 | say time()' _GetMachineMACRoles() started' | 
|---|
| 564 | machine = arg(1) /* May be name or IP */ | 
|---|
| 565 | call VRSet VRWindow(), 'Pointer', 'Wait' | 
|---|
| 566 | say       '  detach 'samba.!nmblookupexe' -A 'machine' 'debuglevel' >'samba.!msg | 
|---|
| 567 | address cmd 'detach 'samba.!nmblookupexe' -A 'machine' 'debuglevel' >'samba.!msg | 
|---|
| 568 |  | 
|---|
| 569 | if VRIsValidObject("DT_STATUSBAR") then ok = VRSet("DT_STATUSBAR","Caption","Obtaining capabilities from "machine) | 
|---|
| 570 | do while stream(samba.!msg,'c','open read') <> "READY:" | 
|---|
| 571 | ok = SysSleep(0.33) | 
|---|
| 572 | if VRIsValidObject("DT_STATUSBAR") then ok = VRSet("DT_STATUSBAR","Caption", VRGet("DT_STATUSBAR","Caption")||'.') | 
|---|
| 573 | end | 
|---|
| 574 | call VRSet VRWindow(), 'Pointer', '<default>' | 
|---|
| 575 | ok = file2stem(samba.!msg,"nmblookup.") | 
|---|
| 576 | Roles = "" | 
|---|
| 577 | MAC = 'xx-xx-xx-xx-xx-xx' | 
|---|
| 578 | do I = 1 to nmblookup.0 | 
|---|
| 579 | select | 
|---|
| 580 | when pos('<1c>', nmblookup.I) > 0 then Roles = Roles||"PDC," /* # */ | 
|---|
| 581 | when pos('<1b>', nmblookup.I) > 0 then Roles = Roles||"LMB," /* + */ | 
|---|
| 582 | when pos('<1d>', nmblookup.I) > 0 then Roles = Roles||"DMB," /* * */ | 
|---|
| 583 | when pos('MAC',  nmblookup.I) > 0 then do | 
|---|
| 584 | parse var nmblookup.I . '=' MAC | 
|---|
| 585 | MAC = strip(MAC) | 
|---|
| 586 | end | 
|---|
| 587 | otherwise nop | 
|---|
| 588 | end | 
|---|
| 589 | end | 
|---|
| 590 | Roles = strip(Roles,,',') | 
|---|
| 591 | if Roles = "" then Roles = "Workstation" | 
|---|
| 592 | say time()' _GetMachineMACRoles() done' | 
|---|
| 593 | return MAC'|'Roles | 
|---|
| 594 |  | 
|---|
| 595 | /*:VRX         _GetMachineNMBStatus | 
|---|
| 596 | */ | 
|---|
| 597 | _GetMachineNMBStatus: procedure expose debuglevel samba. | 
|---|
| 598 | say time()' _GetMachineNMBStatus() started' | 
|---|
| 599 | machine = arg(1) /* name only allowed */ | 
|---|
| 600 | call VRSet VRWindow(), 'Pointer', 'Wait' | 
|---|
| 601 | say       '  detach 'samba.!nmblookupexe' -S 'machine' 'debuglevel' >'samba.!msg | 
|---|
| 602 | address cmd 'detach 'samba.!nmblookupexe' -S 'machine' 'debuglevel' >'samba.!msg | 
|---|
| 603 |  | 
|---|
| 604 | if VRIsValidObject("DT_STATUSBAR") then ok = VRSet("DT_STATUSBAR","Caption","Querying "machine" for roles") | 
|---|
| 605 | do while stream(samba.!msg,'c','open read') <> "READY:" | 
|---|
| 606 | ok = SysSleep(0.33) | 
|---|
| 607 | if VRIsValidObject("DT_STATUSBAR") then ok = VRSet("DT_STATUSBAR","Caption", VRGet("DT_STATUSBAR","Caption")||'.') | 
|---|
| 608 | end | 
|---|
| 609 | call VRSet VRWindow(), 'Pointer', '<default>' | 
|---|
| 610 |  | 
|---|
| 611 | ok = file2stem(samba.!msg,"nmblookup.") | 
|---|
| 612 | IPStr = "" | 
|---|
| 613 | Roles = "" | 
|---|
| 614 | MAC = 'xx-xx-xx-xx-xx-xx' | 
|---|
| 615 | do I = 1 to nmblookup.0 | 
|---|
| 616 | select | 
|---|
| 617 | when pos(machine'<',nmblookup.I) > 0 then do | 
|---|
| 618 | parse var nmblookup.i ip . | 
|---|
| 619 | ip = strip(ip) | 
|---|
| 620 | if pos(ip, ipstr) = 0 then ipstr = ipstr||ip',' | 
|---|
| 621 | end | 
|---|
| 622 | when pos('<1c>', nmblookup.I) > 0 then Roles = Roles||"PDC," /* # */ | 
|---|
| 623 | when pos('<1b>', nmblookup.I) > 0 then Roles = Roles||"LMB," /* + */ | 
|---|
| 624 | when pos('<1d>', nmblookup.I) > 0 then Roles = Roles||"DMB," /* * */ | 
|---|
| 625 | when pos('MAC',  nmblookup.I) > 0 then do | 
|---|
| 626 | parse var nmblookup.I . '=' MAC | 
|---|
| 627 | MAC = strip(MAC) | 
|---|
| 628 | end | 
|---|
| 629 | otherwise nop | 
|---|
| 630 | end | 
|---|
| 631 | end | 
|---|
| 632 | Roles = strip(Roles,,',') | 
|---|
| 633 | if Roles = "" then Roles = "Workstation" | 
|---|
| 634 | ipstr = strip(ipstr,,',') | 
|---|
| 635 | say time()' _GetMachineNMBStatus() done' | 
|---|
| 636 | return IPStr'|'MAC'|'Roles | 
|---|
| 637 |  | 
|---|
| 638 |  | 
|---|
| 639 |  | 
|---|
| 640 | /*:VRX         file2stem | 
|---|
| 641 | */ | 
|---|
| 642 | file2stem: | 
|---|
| 643 | say time()' file2stem() started' | 
|---|
| 644 | msgfile = arg(1) | 
|---|
| 645 | msgstem = arg(2) | 
|---|
| 646 | delmsgfile = translate(arg(3)) | 
|---|
| 647 | if right(msgstem,1) <> '.' then msgstem = msgstem'.' | 
|---|
| 648 | say '  file2stem("'msgfile'","'msgstem'")' | 
|---|
| 649 | dyn = 'drop 'msgstem | 
|---|
| 650 | interpret dyn | 
|---|
| 651 | stemcount = 0 | 
|---|
| 652 | do while lines(msgfile) > 0 | 
|---|
| 653 | stemcount = stemcount + 1 | 
|---|
| 654 | inline = linein(msgfile) | 
|---|
| 655 | if pos('creating lame',inline) > 0 | pos('tdb(',inline) > 0 then do | 
|---|
| 656 | stemcount = stemcount - 1 | 
|---|
| 657 | iterate | 
|---|
| 658 | end | 
|---|
| 659 | dyn = msgstem||stemcount' = inline' | 
|---|
| 660 | interpret dyn | 
|---|
| 661 | end | 
|---|
| 662 | dyn = msgstem||"0 = "stemcount | 
|---|
| 663 | interpret dyn | 
|---|
| 664 | ok = stream(msgfile,'c','close') | 
|---|
| 665 | if delMsgFile <> "NODEL" then ok = SysFileDelete(msgfile) | 
|---|
| 666 |  | 
|---|
| 667 | drop msgfile msgstem | 
|---|
| 668 | say time()' file2stem() done' | 
|---|
| 669 | return stemcount | 
|---|