How to write this command line? - command-line

I'm using oh-my-zsh.
I want to make a zsh command mx google.com
And have it run the following:
dig +short mx $1
And then if I run
a p
where 'p' stands for "previous" (I'm open to other more common conventions here)
I want it to run (hypothetical if previous line outputs 3 IPs):
dig + short a ip1
dig + short a ip2
dig + short a ip3
for each result returned in the previous command.
The commands I want to support with the above convention are a, txt, mx, cname
This was currently all I had:
alias a='f() { dig +short a $1 };f'
but I am not sure how to combine the two.

Related

How do I find the process ID that listens to SOCK_SEQPACKET in C/C++ program

There is a server that starts and listens to a SOCK_SEQPACKET. I think a SOCK_SEQPACKET has a name, say, #Foo. It's per user, so initiated by each Linux user account, and there is only one service per user.
The goal is to make an external tool that forcefully kill the service when something goes wrong. The language is C++.
When I have to kill that service, I use netstat:
$ netstat -lnp | egrep Foo
I would not like to have a dependency on the net-tools package, though. I would like to do this with minimal dependencies on external tools and/or even libraries.
I've tried Google search, and could not find how. I guess I could perhaps read netstat source code to see how they do; I would like to defer that to the last resort, though. I have learned how I could kill the service, using netstat, which gives me dependency on net-tools. The service somehow runs as /proc/self or so. I could visit every process ID in /proc, and see if that looks like the service: see the executable name, etc. However, that is not necessarily sufficient indication to narrow down to that one single process, which uses the #Foo SOCK_SEQPACKET. Now, as non-expert in socket/network programming, I am running out of ideas about how I should proceed.
As #user253751 says, that's not actually a socket type but more of a socket behavior type. As they suggested, it is probably a unix domain socket. Given the '#' sign in it, it is almost certainly using the unix domain socket's "abstract" namespace (which means the socket doesn't have an endpoint directly visible in the filesystem). At the system call level, such endpoints are created with a null byte as the first character (the # is commonly substituted in command line utilities or wherever the socket is surfaced to user space for user convenience). See the unix(7) man page for more details.
Since the socket doesn't appear in the filesystem anywhere, it can be difficult to find the association of process to socket. One way you can find that is through use of the lsof utility -- but that is probably little improvement over the netstat utility.
It appears that the abstract namespace sockets do show up in the /proc/net/unix pseudo-file. In association with that, there is an inode column (second to the last). In conjunction with looking at each process's /proc/<pid>/fd directory, I think you can make the association.
For example, I created a small python program that creates a Unix domain SOCK_SEQPACKET socket and binds it to '#Foo'. That program is here:
import socket, time
sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
sock.bind('\0Foo') # Note the \0 for the initial null byte
time.sleep(10000) # Just hang around while we do other stuff
In a separate terminal window:
gh $ grep '#Foo' /proc/net/unix
0000000000000000: 00000002 00000000 00000000 0005 01 7733102 #Foo
gh $ sudo bash -c 'for proc in /proc/[0-9]*; do ls -l $proc/fd | grep 7733102 && echo $proc; done'
lrwx------ 1 gh gh 64 Feb 2 17:13 3 -> socket:[7733102]
/proc/339264
gh $ ps -fp 339264
UID PID PPID C STIME TTY TIME CMD
gh 339264 22444 0 17:11 pts/3 00:00:00 python3
gh $ ls -l /proc/339264/fd
total 0
lrwx------ 1 gh gh 64 Feb 2 17:13 0 -> /dev/pts/3
lrwx------ 1 gh gh 64 Feb 2 17:13 1 -> /dev/pts/3
lrwx------ 1 gh gh 64 Feb 2 17:13 2 -> /dev/pts/3
lrwx------ 1 gh gh 64 Feb 2 17:13 3 -> 'socket:[7733102]'
Explaining:
First, we do a grep on /proc/net/unix for the '#Foo' socket. That gives us the inode number 7733102 (second to last column). The inode number is unique to every socket on the system.
Next, as root, we do an ls -l /proc/<pid>/fd for each process on the system and grep for the inode number we found in the previous step. When found, we printed out the /proc/<pid> entry. (On linux, that pseudo-directory shows a symlink to a representation of what each file descriptor open in the process is. For sockets, that representation is always socket:[<inode>].) Here we found the process ID is 339264.
The remaining two steps are just confirming that that is in fact, our python process, and you can see its four open files (the first three [stdin, stdout, stderr] all pointing to its terminal's pseudo-tty, the fourth to the socket).
To make this into a more foolproof program, you'd need to account for the fact that the inode number you found in step 1 could be a substring of some other socket's inode number but that is left as an exercise for the reader. :)

grep command to print follow-up lines after a match

how to use "grep" command to find a match and to print followup of 10 lines from the match. this i need to get some error statements from log files. (else need to download use match for log time and then copy the content). Instead of downloading bulk size files i need to run a command to get those number of lines.
A default install of Solaris 10 or 11 will have the /usr/sfw/bin file tree. Gnu grep - /usr/sfw/bin/ggrep is there. ggrep supports /usr/sfw/bin/ggrep -A 10 [pattern] [file] which does what you want.
Solaris 9 and older may not have it. Or your system may not have been a default install. Check.
Suppose, you have a file /etc/passwd and want to filter user "chetan"
Please try below command:
cat /etc/passwd | /usr/sfw/bin/ggrep -A 2 'chetan'
It will print the line with letter "chetan" and the next two lines as well.
-- Tested in Solaris 10 --

Make IPs anonymous in output of Web analytics tool - perl or sed?

I analysed logs with http://www.w3perl.com/, now i want the IPs made anonymous.
So i want them changed in all html-files in the whole directory.
I thought about just always turning the third and fourth octet into the same number for all IPs. But i read something about XOR-ing them - what is that about?
what is the better way to manage the replacing and why? sed or perl or another option?
I am pretty new to this, i hope i searched the other topics enough. I haven't found anything related to my problem.
Thanks in advance and please excuse my English.
This website is just great - i've learned so much in the last days!
Masking IP-Address can be better achieved with perl. You can take a look here for using already available modules so that you won't have to re-invent the wheel. Unfortunately I don't know perl, so I can only offer sed solution.
You can use something like this for replacing all ip-address in your file.
sed 's/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/**masked ip**/g' < yourfile > newfile
Your file:
[jaypal:~/Temp] cat fmp
this is 12.34.55.222 and
21.3.34.5
also there is 133.42.55.23
Step 1: Identify IP-Addresses:
[jaypal:~/Temp] sed 's/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/**&**/g' fmp
this is **12.34.55.222** and
**21.3.34.5**
also there is **133.42.55.23**
Step 2: Replace IP-Address with your mask
[jaypal:~/Temp] sed 's/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/**&**/g' fmp | sed '/\*\*.*\\*\*/s//**masked ip**/'
this is **masked ip** and
**masked ip**
also there is **masked ip**
You can either make sed -i (in-line) substitution or use > to re-direct your output to another file.
Obviously this can be reduced to the following. The above would be useful for debugging as you can view what is being changed before making the change.
[jaypal:~/Temp] sed 's/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/** masked ip **/g' fmp
this is ** masked ip ** and
** masked ip **
also there is ** masked ip **
Good Luck!!
Update:
As posted by Mark in the comments, a perl variant would be -
perl -pe 's/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/** masked ip **/g' < inputfile > outputfile
Update II:
As requested by OP, the following one-liner will find the files and perform the substitution.
find /path/to/dir/ -type f -name "*.html" -exec perl -ibak -pe 's/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/** masked ip **/g' {} \;

Is procmail chrooted or limited in using linux commands?

im using procmail to forward emails to different folders in my Maildir.
I use these two lines to get the FROM and TO from the mail, which works pretty fine.
FROM=`formail -x"From:"`
TO=`formail -x"To:"`
These two commands return the whole line without the From: and To: prefix.
So i get something like:
Firstname Lastname <firstname.lastname#mail-domain.com>
Now i want to extract the email between < and >.
For this i pipe the variable FROM and TO grepping it like this.
FROM_PARSED=`echo $FROM | grep -o '[[:alnum:]+\.\_\-]*#[[:alnum:]+\.\_\-]*'`
TO_PARSED=`echo $TO | grep -o '[[:alnum:]+\.\_\-]*#[[:alnum:]+\.\_\-]*'`
But when i print FROM_PARSED into the procmail log by using LOG=FROM_PARSED, i get an empty string in FROM_PARSED and TO_PARSED.
But if i run these commands on my console, all works fine. I tried many other grepping methods, using grep, egrep, sed and even cut (cutting < and >). All working on console, but i use it in procmail it just returns nothing.
Is it possible that procmail is not allowed to use grep and sed commands? Something like a chroot?
I dont get any error logs in my procmail log. I just want to extract the valid email address from the FROM and TO line. Extracting with formail works, but parsing it with grep or sed fails, even if expression is correct.
Could somebody help? Maybe i need to setup procmail somehow.
Strange.
I added this to the users .procmailrc file
SHELL=/bin/bash
The users shell was set to /bin/false, which is correct because its a mail user, no ssh access at all.
You should properly quote "$FROM" and "$TO".
You will also need to prefix grep with LC_ALL=POSIX to ensure [:alnum:] will actually match the 26 well-known characters + 10 digits of the English alphabet.
You already solved this, but to answer your actual question, it is possible to run procmail in a chroot, but this is certainly not done by Procmail itself. Sendmail used to come with something called the Sendmail Restricted Shell (originally called rsh but renamed to remsh) which allowed system administrators to chroot the delivery process. But to summarize, this is a feature of the MTA, not of Procmail.

Checking Nameserver setup from command line

Is there a way to check if my domain is setup correctly on the nameservers? Ideally I'd like to run a command from command line, alternatively can use a third party tool.
for example, I'm trying to register a domain that's to be hosted on godaddy.com. I have set up the domain and can see it in my DNS list. The servers that are supposed to be setup are ns51.domaincontrol.com and ns52.domaincontrol.com, however my registration is bouncing saying that there are "No Nameservers found for {my new domain}".
I think this is the shortest and quickest command to list your nameservers:
host -t ns yourdomain.com
If you're on a Mac or Unix machine you can do the following from command line:
whois site.com
Toward the end it should give you a list of DNS servers.
You can filter the list, showing only the Name Server information, with:
whois site.com | grep "Name S"
Note that www.site.com and site.com are two different end points and you need to set up appropriately for both of them.
Zonecheck is a free software and can be run from the command line:
% zonecheck stackoverflow.com
ZONE : stackoverflow.com.
NS <= : ns51.domaincontrol.com. [216.69.185.26]
NS : ns52.domaincontrol.com. [208.109.255.26]
_______________
,---------------.|
~~~~ | warning || ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`---------------'
w> Nameservers are all part of the same AS
| Adv: ZoneCheck
| To avoid loosing all connectivity with the authoritative DNS in case
| of a routing problem inside your Autonomous System, it is advised to
| host the DNS on different AS.
`----- -- -- - - -
: All the nameservers are part of the same Autonomous System (AS number
: 26496), try to have some of them hosted on another AS.
`..... .. .. . . .
=> generic
==> SUCCESS (but 1 warning(s))
There is a built-in command line for that: nslookup
Submit it, then write set type=ANY and press enter. After which specify desired domain and you'll get what you are looking for. Alternatively, enter ? and see more options for the nslookup command line.
PS: while this answer comes with a delay, hope it to be useful for others who want to check nameserver/DNS setup from command line.
nm-tool run from the command line will give you much information, not the least of which is the DNS servers you're using. You may have to install this, but many distros have it included.