[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [cobalt-developers] REMOTE_USER variable



> >I am using a .htaccess file to protect a directory/site .  Using
> >perl/cgi I can obtain the REMOTE_USER variable and store or display
> this
> >information.  What I would like to do is display all users that are
> >currently authenticated to this resource. So in effect I want to
> display
> >not only the logged in users REMOTE_USER variable but all REMOTE_USER
> >variables that are currently logged in. Is this possible? Is anyone
> >doing something similar?
> 
> Well, http doesn't support permanent connections like telnet or ssh
> do...
> anyway, you could log all authenticated requests, together with a
> timestamp, and drop any lines older then 5 minutes (or so). A simple
> perl
> script would look like this (usage: "@logged_in_users =
> get_users($ENV{'REMOTE_USER'});" or simply "... = get_users();").
> 
> my $lock_file = "users.lock";
> my $users_file = "users";
> 
> sub get_users(;$)
> {
>    my ($new_user) = @_;
>    my @new_udata = ();
>    my @authenticated = ();
> 
>    lock_users();
>    if( open(USERS, "<${users_file}") )
>    {
>      my @udata = <USERS>;
>      close(USERS);
> 
>      foreach my $user_data (@udata)
>      {
>        chop $user_data;
>        if( $user_data =~ /^([a-zA-Z0-9]+):([0-9]+)$/ )
>        {
>          my $user_name = $1; my $time_stamp = $2;
>          if( $time_stamp >= time() && $user_name ne $new_user )
>          {
>            push(@new_udata, "${user_name}:${time_stamp}\n");
>            push(@authenticated, $user_name);
>          }
>        }
>      }
>      if( defined($new_user) )
>      {
>        # Add this user
>        push(@new_data, sprintf("%s:%d\n", $new_user, time() + 5*60));
>        push(@authenticated, $new_user);
>      }
>      if( open(USERS, ">${users_file}") )
>      {
>        print(USERS @new_udata);
>        close(USERS);
>      }
>      else
>      {
>        error("Couldn't write to ${users_file}: $!\n"); # error()
> defined
> elsewhere
>      }
>    }
>    else
>    {
>      error("Couldn't open ${users_file}: $!\n"); # error() defined
> elsewhere
>    }
>    unlock_users();
>    return(@authenticated);
> }
> 
> sub lock_users()
> {
>    while(-e($lock_file))
>    {
>      select(undef, undef, undef, 0.1); # wait 0.1s
>    }
>    if(open(LOCK, ">${lock_file}"))
>    {
>      print(LOCK "$$\n");
>      close(LOCK);
>    }
>    else
>    {
>      die("Couldn't open ${lock_file}: $!\n");
>    }
> }
> 
> sub unlock_users()
> {
>    if(-e($lock_file))
>    {
>      unlink($lock_file);
>    }
> }
> 
> Ok, so it's not perfect. I would recommend to at least define
> $SIG{'PIPE'}
> to something meaningful, and to define error(), of course. Maybe there
> should be a timeout in lock_users() (it can wait forever...), and some
> way
> to deal with a lock file from a killed/aborted process - for example,
> you
> could check if the process with the pid from $lock_file is actually
> still
> running.
> 
> Read you...
>         Martin Sojka.
> 
 - Hi Martin,
This is great! thanks for the pointers. I'll let you know how it works
out.

Regards, 
Curtis Ross