Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sun-barr!newstop!exodus!appserv!slovax.Eng.Sun.COM!lm From: lm@slovax.Eng.Sun.COM (Larry McVoy) Newsgroups: comp.unix.wizards Subject: Re: Wizard-level questions Message-ID: <395@appserv.Eng.Sun.COM> Date: 28 Jan 91 07:55:35 GMT References: <16048@sdcc6.ucsd.edu> Sender: news@appserv.Eng.Sun.COM Reply-To: lm@slovax.Eng.Sun.COM (Larry McVoy) Organization: Sun Microsystems, Mt. View, CA. Lines: 161 In article <16048@sdcc6.ucsd.edu> cs163wcr@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 #include 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 () { 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@sun.com