Re: How to do same as 'nmap' command from within a D program?

2022-01-22 Thread frame via Digitalmars-d-learn
On Saturday, 22 January 2022 at 20:55:38 UTC, Daren Scot Wilson 
wrote:


I don't see any D std.* libraries that do this. Are there a Dub 
packages I should look at?


If you really want to this in D without any external app or OS 
API you could just ping all possible hosts, see which respond and 
then use `getHostByAddr()` to find the hostname.


Another more professional way is to query the ARP protocol, where 
you send a packet as broadcast to all interfaces in the network 
to find a MAC for a given IP - if any host responses with a MAC, 
the host is up.


You have to build the packet data for yourself, there are 
examples on the web. The socket to use is family:INET, type:RAW 
and protocol:ICMP for ping or RAW for ARP or anything that isn't 
listed in D.


As you can see, it's required to test every possible IP out 
(except for any other discovery protocols supported by your 
network/router). For this reason, any OS does this scan 
periodically and caches the result. On UNIX you can just directly 
read the file `/proc/net/arp`, no need to use nmap.





Re: map question

2022-01-22 Thread forkit via Digitalmars-d-learn
On Saturday, 22 January 2022 at 19:55:43 UTC, Stanislav Blinov 
wrote:




thanks for the explanation. That really helped :-)

writeln( generate!(() => dice(0.6, 1.4)).take(howManyTimes) );
[1, 1, 1, 1, 0]

(or after reading Ali's response - getting rid of rnd, and using 
_ )


writeln( howManyTimes.iota.map!(_ => dice(0.6, 1.4)) );
[1, 0, 1, 1, 1]

They produce exactly the same thing, so I guess it comes down to 
personal choice now.




Re: How to do same as 'nmap' command from within a D program?

2022-01-22 Thread forkit via Digitalmars-d-learn

On Saturday, 22 January 2022 at 22:44:31 UTC, forkit wrote:




and here is how to get the ip (depending on the formatting of 
your output of course)


// ---
module test;

import std;

void main()
{
auto result = execute(["bash", "-c", "nmap -sn 
192.168.11.0/24 | ack -B2 \"Philips\""]);


string ip;

if(canFind(result.to!string, "Host is up"))
{
writeln("Host is up");

string str = result.to!string.chop;
ip = str[ (indexOf(str, "for Philips (") + 10)..$-4 ];
writeln(ip);
}
else
writeln("Host not found.");
}

// 



Re: How to do same as 'nmap' command from within a D program?

2022-01-22 Thread forkit via Digitalmars-d-learn

On Saturday, 22 January 2022 at 23:15:18 UTC, forkit wrote:




oh.. this is better i think...

ip = str[ ((lastIndexOf(str, "(")) + 1) .. lastIndexOf(str, ")") 
];






Re: map question

2022-01-22 Thread Ali Çehreli via Digitalmars-d-learn

On 1/22/22 11:32, forkit wrote:
> trying to make sense of the below:

The generate() solution shown by Stanislav Blinov is suitable here.

>  auto rnd = Random(unpredictableSeed);

Somebody else mentioned this before but none of the programs we've seen 
so far seemed to need a special random number generator. So, the default 
one, which is already randomized, would suffice. Just drop the line above.


>  // ok - using 'e =>' makes sense
>  writeln(howManyTimes.iota.map!(e => rnd.dice(0.6,
> 1.4)).format!"%(%s,%)");

When there is a syntactic need for a variable but that variable is not 
used, the idiomatic way of naming that variable is '_':


howManyTimes.iota.map!(_ => dice(0.6, 1.4))

(Note: I did not write rnd.dice.)

Ali



Re: How to do same as 'nmap' command from within a D program?

2022-01-22 Thread forkit via Digitalmars-d-learn
On Saturday, 22 January 2022 at 20:55:38 UTC, Daren Scot Wilson 
wrote:




is this helpful:

// ---
module test;

import std;

void main()
{
auto result = execute(["bash", "-c", "nmap -sn 
192.168.11.0/24 | ack -B2 \"Phillips\""]);


if(canFind(result.to!string, "Host is up"))
writeln("Host is up");
else
writeln("Host not found.");
}

// ---




How to do same as 'nmap' command from within a D program?

2022-01-22 Thread Daren Scot Wilson via Digitalmars-d-learn
I'm writing a command line program to control certain hardware 
devices. I can hardcode or have in a config file the IP addresses 
for the devices, if I know that info. If I don't?  Then I run an 
'nmap' command and look for the devices.  But why should I, a 
human, have to do any work like that? Bah!  I want my program to 
obtain this information at runtime, automatically, and "don't 
make me think".


One thing that might make it tough is nmap must run sudo to 
report the desired information. (To my knowledge; I'm no 
networking expert.) The exact command is:


sudo nmap -sn 192.168.11.0/24  |ack -B2 "Philips"

The IP address is printed two lines before the name match (ack is 
"better than grep"). Typical nmap output is a series of chunks of 
text like this:


Nmap scan report for 192.168.11.10
Host is up (0.00033s latency).
MAC Address: 00:17:88:4D:97:4D (Philips Lighting BV)

I don't see any D std.* libraries that do this. Are there a Dub 
packages I should look at?





Re: map question

2022-01-22 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 22 January 2022 at 19:32:07 UTC, forkit wrote:

trying to make sense of the below:


// ---
module test;

import std;

void main()
{
auto rnd = Random(unpredictableSeed);

int howManyTimes = 5;

// ok - using 'e =>' makes sense
writeln(howManyTimes.iota.map!(e => rnd.dice(0.6, 
1.4)).format!"%(%s,%)");


// ok - though using 'howManyTimes =>' doesn't make much 
sense??
writeln(howManyTimes.iota.map!(howManyTimes => 
rnd.dice(0.6, 1.4)).format!"%(%s,%)");


// NOT ok - using '5 =>' - but isn't this effectively the 
same as above line?
//writeln(howManyTimes.iota.map!(5 => rnd.dice(0.6, 
1.4)).format!"%(%s,%)");

}

// ---


No, it's not the same. 'Tis not really a "map question", looks 
more like a question about


https://dlang.org/spec/expression.html#function_literals (see 
#10).


In the second case, you're defining a lambda with single 
parameter named `howManyTimes`, which is not at all related to 
your local variable of the same name. Third case is invalid, as 
you're effectively trying to do this:


auto func(T)(T 5) { return rnd.dice(0.6, 1.4); }

Which, of course, doesn't make any sense, does it? :)

Given your use case (call a function N times), I think `generate` 
would be more appropriate here:


```d
import std.random;
import std.stdio;
import std.range : generate, take;

void main()
{
auto rnd = Random(unpredictableSeed);
int howManyTimes = 5;
generate!(() => rnd.dice(0.6, 
1.4)).take(howManyTimes).writeln;

}

```


Re: forward tuple arg to local variable + dtor

2022-01-22 Thread vit via Digitalmars-d-learn
On Saturday, 22 January 2022 at 19:01:09 UTC, Stanislav Blinov 
wrote:

On Saturday, 22 January 2022 at 18:00:58 UTC, vit wrote:


[...]


Take by value and make a copy without forwarding:

```d
import std.typecons : Tuple;
import std.meta : allSatisfy;

[...]


Thanks, second options is what I need. (In my case forwarding is 
more complex because weak ptrs need lock()).





map question

2022-01-22 Thread forkit via Digitalmars-d-learn

trying to make sense of the below:


// ---
module test;

import std;

void main()
{
auto rnd = Random(unpredictableSeed);

int howManyTimes = 5;

// ok - using 'e =>' makes sense
writeln(howManyTimes.iota.map!(e => rnd.dice(0.6, 
1.4)).format!"%(%s,%)");


// ok - though using 'howManyTimes =>' doesn't make much 
sense??
writeln(howManyTimes.iota.map!(howManyTimes => rnd.dice(0.6, 
1.4)).format!"%(%s,%)");


// NOT ok - using '5 =>' - but isn't this effectively the 
same as above line?
//writeln(howManyTimes.iota.map!(5 => rnd.dice(0.6, 
1.4)).format!"%(%s,%)");

}

// ---


Re: forward tuple arg to local variable + dtor

2022-01-22 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 22 January 2022 at 18:00:58 UTC, vit wrote:


I want implement something like this:


Scratch the previous reply, 'twas a brain fart... Simply take by 
value, no need for extra copies at all in that case. Arguments 
themselves will become those copies as needed.


```d
import std.meta : allSatisfy;

enum bool isRcPtr(T) = is(T == RcPtr!U, U);

//@safe access to data of multiple ref counted objects:
public auto apply(alias fn, Args...)(Args args)
if (allSatisfy!(isRcPtr, Args)) {

@property auto ref elm(alias param)()@trusted{
return param.get();
}

return fn(staticMap!(elm, args));
}
```


Re: Ensuring allocation isn't thread-local?

2022-01-22 Thread Jaime via Digitalmars-d-learn

On Saturday, 22 January 2022 at 19:06:38 UTC, Adam D Ruppe wrote:


No. Anything allocated with `new` is not thread local... and 
even if it was, you can send the pointer to other threads 
anyway.


The only things in thread local storage are the direct values 
in the non-shared global variables. What they actually point to 
is just generally on the main heap just like anything else.


Thanks for the response. Good to know.


Re: Ensuring allocation isn't thread-local?

2022-01-22 Thread Adam D Ruppe via Digitalmars-d-learn

On Saturday, 22 January 2022 at 18:55:30 UTC, Jaime wrote:
A) Do I need to worry about data being / not being in 
thread-local storage?


No. Anything allocated with `new` is not thread local... and even 
if it was, you can send the pointer to other threads anyway.


The only things in thread local storage are the direct values in 
the non-shared global variables. What they actually point to is 
just generally on the main heap just like anything else.


Re: forward tuple arg to local variable + dtor

2022-01-22 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 22 January 2022 at 18:00:58 UTC, vit wrote:


I want implement something like this:
...


Take by value and make a copy without forwarding:

```d
import std.typecons : Tuple;
import std.meta : allSatisfy;

enum bool isRcPtr(T) = is(T == RcPtr!U, U);

//@safe access to data of multiple ref counted objects:
public auto apply(alias fn, Args...)(Args args)
if (allSatisfy!(isRcPtr, Args)) {

Tuple!Args params = args; // borrow all

@property auto ref elm(alias param)()@trusted{
return param.get();
}

return fn(staticMap!(elm, args)); // staticMap over original 
args tuple

}
```

Or make a helper function that takes by value and forward to that:

```d
template apply(alias fn)
{
private auto impl(Args...)(Args args)
{
@property auto ref elm(alias param)()@trusted{
return param.get();
}
return fn(staticMap!(elm, args));
}

auto apply(Args...)(auto ref Args args)
if (allSatisfy!(isRcPtr, Args))
{
import core.lifetime : forward;
return impl(forward!args); // impl takes by value - 
RcPtrs passed by reference will be copied

}
}
```


Ensuring allocation isn't thread-local?

2022-01-22 Thread Jaime via Digitalmars-d-learn

Howdy.

How do I make sure data isn't allocated thread-local, if I also 
want to immediately use it in a thread-local way, because, for 
instance, I happen to already possess its intended mutex, which 
was allocated before it?


Is this sufficient? Also, is it even something to worry about?

```d
// for classes
cast(T) new shared(T)(...)
// otherwise
cast(T*) new shared(T)(...)
```

For example, this is the full relevant excerpt of my WIP, 
untested code so far:


```d
private struct Message {
ulong sender;
Variant payload;
}

private struct MessageQueue {
DList!Message* data;
Mutex mutex;
Condition enqueued; // <-- Should fire on insertion.
}

// A queue for each recipient thread.
private shared(MessageQueue[ulong]) messageTable;
private Mutex tableMutex; // <-- Protects messageTable.

/*
This function should only be called by a thread holding 
tableMutex.

We don't acquire tableMutex in the function itself
because maybe the caller wants to do something else with it too.
*/
private ref MessageQueue getQueue(ulong recipient) {
auto nsMessageTable = cast(MessageTable[ulong]*) 


MessageQueue* qptr = recipient in *nsMessageTable;
if (qptr is null) {
auto newMutex = cast(Mutex) new shared(Mutex);
qptr = &((*nsMessageTable)[recipient] = MessageQueue(
/*
This is the part where I instantiate stuff as shared
and then immediately cast away sharing
because we're already holding tableMutex.
*/
cast(DList!Message*) new shared(DList!Message),
newMutex,
cast(Condition) new shared(Condition)(newMutex)
));
}
return *qptr;
}
```

(I know it's probably not a good idea to try to implement an 
alternative to std.concurrency, and I should just use 
std.concurrency instead, but I have a good reason, and that 
reason is hands-on learning.)


Anyway, yeah, to reiterate: do I have the right idea here? That 
is:
A) Do I need to worry about data being / not being in 
thread-local storage?
B) If so, how do I make sure it's not there? Will my approach so 
far suffice?

C) If not, what's a better way?

Thanks in advance for any guidance.


Re: forward tuple arg to local variable + dtor

2022-01-22 Thread vit via Digitalmars-d-learn

On Saturday, 22 January 2022 at 17:23:12 UTC, Ali Çehreli wrote:

On 1/22/22 07:17, vit wrote:

> Why local variable of type tuple call destructors immediately
after
> initialization?

I don't even understand where the local variable comes from. If 
you want a pair of Foo objects, I would use std.typeconst.Tuple.


Otherwise I would use AliasSeq as I understand it like the 
following:


alias tup = AliasSeq!(Foo, Foo);

static foreach(Type; tup) {{
  Type x;
  writeln("check(", x.i, "): ", cast(void*));
}}

So, to me, AliasSeq!(Foo, Foo) is just a pair of types. I 
instantiate an object for each type individually and use it 
inside.


Ali


I want implement something like this:

```d
import std.stdio : writeln;
import std.meta : AliasSeq, staticMap;
import core.memory : pureMalloc, pureFree;
import core.lifetime : emplace, forward;


void main()@safe{
auto rc1 = RcPtr!int.make(1);   //ref counted pointer

long result = 0;

//apply can be @safe
apply!((ref int a, ref long b){
rc1 = null;	//apply has copy of rc1, a is not 
dangling reference

result = a + b;

})(rc1, RcPtr!long.make(2));

assert(result == 3);
}

//@safe access to data of multiple ref counted objects:
public auto apply(alias fn, Args...)(scope auto ref Args 
args){
	Args params = forward!args;	//copy lvalue and move rvalue 
args


@property auto ref elm(alias param)()@trusted{
return param.get();
}

return fn(staticMap!(elm, params));

}

//simple implementation of ref counted pointer
struct RcPtr(T){

private Payload* payload;

private this(Payload* payload)@safe{
this.payload = payload;
}

//copy ctor
public this(ref typeof(this) rhs){
this.payload = rhs.payload;
if(payload)
payload.count += 1;
}

//make data
public static auto make(Args...)(auto ref Args args){
Payload* payload = ()@trusted{
return cast(Payload*)pureMalloc(Payload.sizeof);
}();
emplace(payload, forward!args);
return RcPtr(payload);  
}

public ~this(){
this.opAssign(null);
}

//release payload
void opAssign(typeof(null) nil){
if(payload){
payload.count -= 1;
if(payload.count == 0){
destroy(*payload);
()@trusted{
pureFree(payload);
}();
payload = null;
}
}
}

//
ref T get()@system{
assert(payload);
return payload.data;
}

private struct Payload{
int count = 1;
T data;

this(Args...)(auto ref Args args){
data = T(forward!args);
}
}
}



```


Re: forward tuple arg to local variable + dtor

2022-01-22 Thread Ali Çehreli via Digitalmars-d-learn

On 1/22/22 07:17, vit wrote:

> Why local variable of type tuple call destructors immediately after
> initialization?

I don't even understand where the local variable comes from. If you want 
a pair of Foo objects, I would use std.typeconst.Tuple.


Otherwise I would use AliasSeq as I understand it like the following:

alias tup = AliasSeq!(Foo, Foo);

static foreach(Type; tup) {{
  Type x;
  writeln("check(", x.i, "): ", cast(void*));
}}

So, to me, AliasSeq!(Foo, Foo) is just a pair of types. I instantiate an 
object for each type individually and use it inside.


Ali



Re: forward tuple arg to local variable + dtor

2022-01-22 Thread vit via Digitalmars-d-learn

On Saturday, 22 January 2022 at 14:23:32 UTC, Adam Ruppe wrote:
You can't forward to a local variable. Local variables will be 
a copy of the tuple. forward only actually works if sent 
*directly* to another function call.


There's a bunch of things in D that only work in function 
parameter lists and not local variables. This is one of them.


Thanks,
Why local variable of type tuple call destructors immediately 
after initialization?


```d
import std.stdio : writeln;
import std.meta : AliasSeq;

struct Foo{
int i;

this(int i){
this.i = i;
writeln("ctor(", i, "): ", cast(void*));
}

~this(){
writeln("dtor(", i, "): ", cast(void*));
i *= -1;
}
}


void main(){
{
AliasSeq!(Foo, Foo) tup;

static foreach(alias x; tup)
writeln("check(", x.i, "): ", cast(void*));	//x is 
destructed

}
}

```

Print:
```
dtor(0): 7FFF30D76868
dtor(0): 7FFF30D76858
check(0): 7FFF30D76858 //dangling?
check(0): 7FFF30D76868 //dangling?
```



Re: forward tuple arg to local variable + dtor

2022-01-22 Thread Adam Ruppe via Digitalmars-d-learn
You can't forward to a local variable. Local variables will be a 
copy of the tuple. forward only actually works if sent *directly* 
to another function call.


There's a bunch of things in D that only work in function 
parameter lists and not local variables. This is one of them.


forward tuple arg to local variable + dtor

2022-01-22 Thread vit via Digitalmars-d-learn

Hello,

Why is tuple variable `params` immediately destructed after its 
construction?

Why is `check(-2)` after `dtor(2)`?

Code:
```d
import std.stdio : writeln;
import core.lifetime : forward, move;

struct Foo{
int i;

this(int i){
this.i = i;
writeln("ctor(", i, "): ", cast(void*));
}

~this(){
writeln("dtor(", i, "): ", cast(void*));
i *= -1;
}
}

void seq(Args...)(auto ref Args args){
Args params = forward!args;
writeln("params initialized");

alias foo = params[0];
writeln("check(", foo.i, "): ", cast(void*));

}

void main(){
writeln("Foo(1):");
{
auto foo = Foo(1);
writeln("check(", foo.i, "): ", cast(void*));
}

writeln("\nFoo(2):");
seq(Foo(2));
}


```

Output:
```
Foo(1):
ctor(1): 7FFEBCAF0538
check(1): 7FFEBCAF0538
dtor(1): 7FFEBCAF0538

Foo(2):
ctor(2): 7FFEBCAF0548
dtor(2): 7FFEBCAF04F0
params initialized
check(-2): 7FFEBCAF04F0
dtor(0): 7FFEBCAF0558
```




Is anyone planning to participate in Google HashCode 2022?

2022-01-22 Thread Siarhei Siamashka via Digitalmars-d-learn

Hello,

I'm just trying to see if it's maybe possible to find some 
teammates here for 
https://codingcompetitions.withgoogle.com/hashcode ?


That said, I have never participated in HashCode before and I'm 
not exactly committed yet. So I may abandon this idea if it 
doesn't work out and/or nobody is interested. I have also posted 
a comment on codeforces: 
https://codeforces.com/blog/entry/98986?#comment-880127


Re: automate tuple creation

2022-01-22 Thread forkit via Digitalmars-d-learn
On Saturday, 22 January 2022 at 01:33:16 UTC, Steven 
Schveighoffer wrote:



That second `valuesPerRecord` is not used in the lambda, and 
also it's not referring to the original element, it's the name 
of a parameter in the lambda.


Are you sure this is doing what you want?

-Steve


It just worked, so i didn't think about it too much.. but it 
seems to work either way.


And to be honest, the only part of it I understand, is the dice 
part ;-)


In any case I changed it:

from: valuesPerRecord =>
to:  i =>

// 

void CreateDataFile(const(int) recordsNeeded, const(int) 
valuesPerRecord, const(string) fname)

{
auto rnd = Random(unpredictableSeed);

auto file = File(fname, "w");
scope(exit) file.close;

Appender!string bigString = appender!string;
bigString.reserve(recordsNeeded);

const int iotaStartNum = 100_000_001;

foreach(i, id; iota(iotaStartNum, iotaStartNum + 
recordsNeeded).enumerate)

{
bigString
~= id.to!string
~ ","
~ valuesPerRecord.iota.map!(i => rnd.dice(0.6, 
1.4)).format!"%(%s,%)"

~ "\n";
}

file.write(bigString[]);
}

// ---