tchrist@convex.com (Tom Christiansen) (12/17/90)
Once upon a time I had an annoying problem: I diff the run of a nightly find to discover changes to setid files and devices. Now, I happen to have several accounts, like uucp and notes, that have files of this sort and with more than one login to each uid, so every time the passwd and group files hash (YP), I pull out a different id and so get reams of nightly output. This annoyed me. So I wrote the following filter to convert everything out of 'find -ls' back into numbers so it would stop changing: #!/usr/bin/perl $fmt = 'a22 A9 A8 a*'; while (<>) { ($pre, $login, $group, $post) = unpack($fmt, $_); print pack($fmt, $pre, &get(*login), &get(*group), $post); } sub get { local(*id) = @_; $id{$id} = $id =~ /^\d+$/ ? $id : &id unless defined $id{$id}; $id{$id}; } sub login { (getpwnam($id))[2]; } sub group { (getgrnam($id))[2]; } I would say that this is an interesting program, eh? :-) If this isn't a great demo of Perl's um, unique, scoping behavior, I don't know what is. If you think that's scary, note that if we s/get/id/g the program still works! --tom -- Tom Christiansen tchrist@convex.com convex!tchrist "With a kernel dive, all things are possible, but it sure makes it hard to look at yourself in the mirror the next morning." -me
tchrist@convex.COM (Tom Christiansen) (12/17/90)
Crud -- I was using GNU find. If you use real BSD find (don't ask me about SysV, Brandon :-), you need a26 as the first format field. --tom -- Tom Christiansen tchrist@convex.com convex!tchrist "With a kernel dive, all things are possible, but it sure makes it hard to look at yourself in the mirror the next morning." -me
tchrist@convex.COM (Tom Christiansen) (12/19/90)
No one has said anything, except one person through mail. Here is the slightly touched up code that gets 'find -ls' output. #!/usr/bin/perl $fmt = 'a26 A9 A8 a*'; while (<>) { ($pre, $login, $group, $post) = unpack($fmt, $_); print pack($fmt, $pre, &id(*login), &id(*group), $post); } sub id { local(*id) = @_; $id{$id} = $id =~ /^\d+$/ ? $id : &id unless defined $id{$id}; $id{$id}; } sub login { (getpwnam($id))[2]; } sub group { (getgrnam($id))[2]; } Now answer me these questions three: 1. Why is this (or isn't this) a recursive program? 2. What are the associative arrays in this program, by name? 3. What are their favorite colors? People who already know the answers becasue they've corresponded with me please hold back until we get some fun tries. --tom -- Tom Christiansen tchrist@convex.com convex!tchrist "With a kernel dive, all things are possible, but it sure makes it hard to look at yourself in the mirror the next morning." -me
evans@decvax.DEC.COM (Marc Evans) (12/19/90)
In article <111559@convex.convex.com>, tchrist@convex.COM (Tom Christiansen) writes: |> Crud -- I was using GNU find. If you use real BSD find (don't ask me |> about SysV, Brandon :-), you need a26 as the first format field. Under OSF/1.0 you need a25 (although I thought that this was suppose to be BSD4.4 compatible). - Marc -- =========================================================================== Marc Evans - WB1GRH - evans@decvax.DEC.COM | Synergytics (603)635-8876 Unix and X Software Contractor | 21 Hinds Ln, Pelham, NH 03076 ===========================================================================
tchrist@convex.COM (Tom Christiansen) (12/21/90)
From the keyboard of tchrist@convex.COM (Tom Christiansen): :Now answer me these questions three: (Before I jump on the plane to head for True Cold, here are some answers...) : 1. Why is this (or isn't this) a recursive program? It isn't -- the *id pass-by-name assignment in &id changes which &id your talking about. [Someone was explaining to me the difference between pass-by-name and pass-by-reference, and perl's style seems more the former than the latter.] If you considereed the *id assignment some kind of funky conditional, I guess you might possibly construe it to be a potentially recursive program, but that would be stretching it, and anyway, in this case it doesn't do that. : 2. What are the associative arrays in this program, by name? There are 2 associative arrays used to cache names and values. These are %group and %login. However, to the program, they are always known as %id, but which one it means varies between calls, so it would be arguably correct (and certainly a lot more fun) to say that they are %id and %id. : 3. What are their favorite colors? One respondent said "Red. No Blue!" His message trailed off in an "ARGGGGGGGGGGGGGGGGG!" as he was cast in the Abyss, and I have not heard from him since. You should always answer Blue to questions like this, or at the very least be decisive. --tom -- Tom Christiansen tchrist@convex.com convex!tchrist "With a kernel dive, all things are possible, but it sure makes it hard to look at yourself in the mirror the next morning." -me