What file and line number is pcap_findalldevs() defined in? - libpcap

What file and line number is pcap_findalldevs() defined in?. I am looking in the libpcap source for the place where pcap_findalldevs() is defined. I found the prototype in pcap.h but where is the complete functionality defined?

Let's see:
# git clone git://git.debian.org/git/users/rfrancoise/libpcap.git
Cloning into libpcap...
[snap]
# grep -ri pcap_findalldevs libpcap |grep '{'
libpcap/fad-sita.c:int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) {
Seems my lucky day !
Here complete source code of this function:
int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) {
*alldevsp = 0;
strcpy(errbuf, "");
if (acn_parse_hosts_file(errbuf))
{
return -1;
}
if (acn_findalldevs(errbuf))
{
return -1;
}
*alldevsp = acn_if_list;
acn_if_list = 0;
return 0;
}
Then, the answer of your question is: fad-sita.c !

It's defined in several places, because the way it's done depends on the OS on which you're running. On Windows with WinPcap, it's defined in fad-win32.c; on UN*Xes that have getifaddrs(), it's defined in fad-getad.c; on Solaris 8 or later, it's defined in fad-glifc.c; on other UN*Xes that support packet capture on local interfaces, it's defined in fad-gifc.c; on UN*Xes that don't support packet capture at all, it's defined (to return no interfaces) in fad-null.c; and, if whoever configured and built libpcap happened to configure in support for capturing from remote devices provided by SITA, it's defined in fad-sita.c.
(Yes, the other answer is wrong; they should not have assumed that those of us who write code in libpcap all like putting the opening curly brace of a function on the same line as the name of the function - I don't, and won't, do that.)

Related

How do external functions return data in Regina Rexx?

I've installed the Regina Rexx package (version 3.9.1) in Cygwin on Windows 10. To test it out, I wrote the following code:
caller:
#!/usr/bin/rexx
x = 'callee'() ; say 'callee returned' x ; exit
callee:
#!/usr/bin/rexx
say 'In callee' ; return 42
When I invoke caller, I expect to see:
> ./caller
In callee
callee returned 42
And in fact, this is exactly what I do see when both execs are in my current directory. However, when I move them to a different directory in $PATH and invoke caller, I see:
> ./caller
caller returned In callee
This was ... unexpected. If there's an explanation of the behavior in the Regina Rexx manual, I'm not seeing it. Am I missing something? Thanks.
It turns out that Rexx execs can be used as external functions only if they reside in a directory mentioned in the REGINA_MACROS variable, like so:
export REGINA_MACROS="${HOME}/subdir:/maybe/somewhere/else"
Without this, the called routine is treated as just another executable. The return value is all stdout lines with a space delimiter between them. Any stderr output is sent to the screen (or redirected) as usual.

TCL Checking Environment Variables

So I have been trying to find an answer for this for a bit and could not find the answer on the internet. I need to check to see if an environment variable exists. I thought I had the right code but it keeps returning false.
if { [info exists ::env(USER)] } {
RAT::LogMsg INFO "Found USER"
} else {
RAT::LogMsg INFO "Nope!"
}
Any ideas?
You might want to check what environment variables are actually set; I don't think that USER is one of the guaranteed ones.
RAT::LogMsg INFO "Got these env-vars: [lsort [array names ::env]]"
If puts stdout works in your environment, you can try doing:
parray ::env
(The parray command is a procedure that pretty-prints an array.)
To get the current username reliably, check out the tcl_platform array's user element. That array is generated internally by Tcl (well, with probes to relevant basic OS APIs) instead of by looking at environment variables, and that particular element is always present back at least as far as Tcl 8.4.
RAT::LogMsg INFO "Username is $::tcl_platform(user)"
I've just noticed that the documentation is wrong: it says that the user element comes from USER and/or LOGNAME environment variables. It doesn't, and doesn't in at least 8.5 and 8.6. (And it's definitely my mistake. I forgot to update the code when I fixed this. Ooops!)
You have the right code, test in tclsh:
% if {[info exists ::env(USER)]} {puts "found $::env(USER)"}
found strobel
%
The problem must be in your environment.

Static detection of errors in Tcl scripts

I have developed some code, and I'm facing problem with error flagging of the Tcl interpreter on a Linux machine.
#!/usr/bin/tclsh
if {1} {
puts "abc1"
} elseif {} {
puts "abc2"
}
The above code is not flagging error for "elseif" condition until it get into the
elseif condition.
Is there any way to check this kind of typo error done unintentionally.
Tcl does not find errors at compilation time, and in the the sample above it can determine that it will never need to examine the elseif clauses in the first place; it just issues that first puts directly.
Now, in the case where there is a non-trivial first condition it is the case that the errors in the elseif expression are not reported until they are reached. This is how the semantics of Tcl — and especially the if command — are defined; errors in evaluation (as opposed to gross major syntax) are reported at the time of execution of the command. I can understand your frustration with this, and suggest that you check out the Tcler's Wiki page on static syntax analysis tools, which can flag up potential problems for you (under very modest assumptions that are virtually always true). In particular, I have heard good things about Frink and the checker tool in TDK (the latter being a commercial tool, but very high quality).
To elaborate on Donal's answer, Tcl does not find errors at compile time because in the general case it cannot be done, any code executed before the if might have redefined the if command, so it could be valid, the only way to determine if this is the case is to run the code (i.e. this is the halting problem)
consider this script:
gets stdin input
if {$input == "fail"} {
rename if if_
proc if {arg1 arg2 arg3} {
puts "ha ha"
}
}
if {1} { puts "success"}
clearly it is impossible to statically determine if the if {1} line has the right number of arguments without running the program
TCL really has virtually no syntax, there is nothing a compiler can check, the best you can do is Lint style warnings, which will only be accurate in some cases
Tcl does not find errors at compilation time, But we can check the syntax using regexp.
Match the pattern " elseif { ", If present check whether there is any characters within the "}" curly brace. If nothing present then print an error message.
There are tcl static syntax checker that can find such problems.
Here is the list of such checkes: http://wiki.tcl.tk/3162
The ttclchecker http://www.xdobry.de/ttclcheck
produces following error message for this short script
stackoverflow.tcl:4: error in expression missing operator <<{}>>

How do you save and parse a command output in Expect?

I am half-way through writing an Expect script on a Linux server which is supposed to telnet to a router in order to collect some system information. So far my script can successfully make the connection, run a router command, disconnect and terminate.
The command displays a few lines which I need to parse, something I am not sure how to do in Expect. How can I save the output, grep a line, then a column from the line, and finally save the result in a file? If possible, I would like to use Expect entirely rather than a work-around (for example Expect embdded in Bash).
Thanks for your time.
jk04
Two tips for expect development:
autoexpect to lay out a framework for your automation
exp_internal 1 to show verbosely what expect is doing internally. This one is indispensable when you can't figure out why your regular expression isn't capturing what you expect.
basically, $expect_out(buffer) [1]. holds the output from last expect match to the current one. you can find your command output there.
and for the string manipulation, you can simply employ the tcl's built-in [2][3].
"How to access the result of a remote command in Expect" http://wiki.tcl.tk/2958
"regexp" http://wiki.tcl.tk/986
"string match" http://wiki.tcl.tk/4385
I've faced and solved a similar problem for interacting with bash. I believe the approach generalizes to any other interactive environment that provides no-op, fixed-string output.
Basically, I wrap the command with two fixed strings and then search for the pattern that includes these strings at the beginning and end, and save the content in between them. For example:
set var "";
expect $prompt { send "echo PSTART; $command; echo PEND;\r"; }
expect {
-re PSTART\r\n(.*)PEND\r\n$prompt { set var [ string trim $expect_out(1,string) ]; send "\r"; }
-re $prompt { set var "" ; send "\r"; }
timeout { send_user "TIMEOUT\n"; exit }
}
I suspect that this approach would work with a shell's comment characters as well, or a simple status command that returns a known output.
Then you can do whatever you need with the content of 'var'.

restart multi-threaded perl script and close mysql connection

I have a Perl script that reads a command file and restarts itself if necessary by doing:
myscript.pl:
exec '/home/foo/bin/myscript.pl';
exit(0);
Now, this works fine except for one issue. The thread that reads the command file does not have access to the DBI handle I use. And over a number of restarts I seem to build up the number of open mysql connections till I get the dreaded "Too Many Connections" error. The DBI spec says:
"Because of this (possibly temporary) restriction, newly created threads must make their own connections to the database. Handles can't be shared across threads."
Any way to close connections or perhaps a different way to restart the script?
Use a flag variable that is shared between threads. Have the command line reading thread set the flag to exit, and the thread holding the DB handle release it and actually do the re-exec:
#!/usr/bin/perl
use threads;
use threads::shared;
use strict; use warnings;
my $EXIT_FLAG :shared;
my $db_thread = threads->create('do_the_db_thing');
$db_thread->detach;
while ( 1 ) {
sleep rand 10;
$EXIT_FLAG = 1 if 0.05 > rand or time - $^T > 20;
}
sub do_the_db_thing {
until ( $EXIT_FLAG ) {
warn sprintf "%d: Working with the db\n", time - $^T;
sleep rand 5;
}
# $dbh->disconnect; # here
warn "Exit flag is set ... restarting\n";
exec 'j.pl';
}
You could try registering an atexit function to close the DBI handle at the point where it is opened, and then use fork & exec to restart the script rather then just exec. The parent would then call exit, invoking the atexit callback to close the DBI handle. The child could re-exec itself normally.
Edit: After thinking for a couple more minutes, I believe you could skip the atexit entirely because the handle would be closed automatically upon the parent's exit. Unless, of course, you need to do a more complex operation upon closing the DB handle than a simple filehandle close.
my $pid = fork();
if (not defined $pid) {
#Could not fork, so handle the error somehow
} elsif ($pid == 0) {
#Child re-execs itself
exec '/home/foo/bin/myscript.pl';
} else {
#Parent exits
exit(0);
}
If you expect a lot of connections, you probably want DBI::Gofer to act as a DBI proxy for you. You create as many connections in as many scripts as you like, and DBI::Gofer shares them when it can.