Wizard-level questions
Larry McVoy
lm at slovax.Eng.Sun.COM
Mon Jan 28 18:55:35 AEST 1991
In article <16048 at sdcc6.ucsd.edu> cs163wcr at sdcc10.ucsd.edu (I support the U.N.) writes:
>[1] Can you access a file by its i-node number? Something like
> (for C code) FILE *iopen (int inode, char *mode) ?
Program included below. This program does an internal file tree walk
to find the inode. Slow, but quite portable, contrary to a supposed
wizard's opinion.
>[2] With Internet sockets, how does a machine accept()ing a
> socket connection know what machine is calling it? Does
> it rely on the calling program to tell it?
Go look at ethernet packets. They have both a sender and a destination.
The sender field, after going through a few protocol layers, gets jammed
into one of the accept(2) args.
>[3] I have a server program that reads my mail and does various
> functions. One thing I would like it to do is send a "write"
> message to other users when it gets a letter with subject
> "WRITE user", sending the letter body as the message, but I
> can't get write to work unless the output is a tty. How do
> I fool write into thinking my pipe is a tty?
Oh, I suspect a little perl script will do it. That's included below as well.
Yes, I was bored this evening. :-)
>[4] How did you become a Unix Wizard? I'm learning various
> features as I go, as I think of a use for them and/or
> learn about them. Is there a more organized/better way?
Use the force, read the source.
# This is a shell archive. Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file". (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# iopen.c wruser
echo x - iopen.c
cat > "iopen.c" << '//E*O*F iopen.c//'
#include <ftw.h>
#include <sys/stat.h>
static int _inum; /* XXX - won't work when multi threaded */
/* could be a function */
#ifdef MAIN
static char *_path; /* just so we can print it out */
#endif
iopen(mnt, inum)
char *mnt;
{
char *mine();
char *path;
int fd;
_inum = inum;
path = (char*)ftw(mnt, mine, 32); /* XXX - 32 */
if (path == (char*)0)
return (-1);
if ((fd = open(path, 2)) == -1)
fd = open(path, 0);
#ifdef MAIN
_path = path;
#endif
return (fd);
}
static char*
mine(p, sp, flags)
char *p;
struct stat *sp;
{
if (sp->st_ino == _inum) {
return (p);
}
return (0);
}
#ifdef MAIN
main(ac, av)
char **av;
{
int fd;
if (ac != 3) {
printf("usage: %s mntpoint inum\n", av[0]);
exit(1);
}
fd = iopen(av[1], atoi(av[2]));
if (fd == -1) {
printf("%s: can't find ino %d\n", atoi(av[2]));
exit(2);
}
printf("open of %s, ino %d, returns %d\n", _path, atoi(av[2]), fd);
}
#endif
//E*O*F iopen.c//
echo x - wruser
cat > "wruser" << '//E*O*F wruser//'
#!/bin/perl
# stolen from vacation.pl
@lines = <>; # schlep 'em in
foreach $_ (@lines) {
last if /^\n/;
next unless /^Subject: WRITE /;
$buf = $_;
$buf =~ s/Subject: WRITE //;
split(/[ \t\n]+/, $buf);
foreach $u (@_) {
$user{$u} = 1;
}
$found++;
last;
}
if (!defined $found) {
#
# Do whatever you would normally do in the case that
# this is normal mail.
# I just copy it to stdout.
foreach $_ (@lines) {
print;
}
exit 0;
}
#
# OK, let's find the user[s] we want.
#
open(WHO, "/usr/bin/who|") || die "No who?";
while (<WHO>) {
split;
if ($user{$_[0]} == 1) {
open(W, "|/bin/write $_[0] $_[1]") || die "write $_[0] $_[1]";
foreach $_ (@lines) {
print W;
}
close(W);
}
}
close(WHO);
exit 0;
//E*O*F wruser//
echo Possible errors detected by \'wc\' [hopefully none]:
temp=/tmp/shar$$
trap "rm -f $temp; exit" 0 1 2 3 15
cat > $temp <<\!!!
57 159 925 iopen.c
45 130 727 wruser
102 289 1652 total
!!!
wc iopen.c wruser | sed 's=[^ ]*/==' | diff -b $temp -
exit 0
---
Larry McVoy, Sun Microsystems (415) 336-7627 ...!sun!lm or lm at sun.com
More information about the Comp.unix.wizards
mailing list