/* PIPServer - A deamon for finger protocol v2
*
* Copyright (C) 1999 Michael Baumer <baumi@vis.ethz.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* Functions for compatibility with the GNU Finger site daemon
*
* This is intended to allow a site to run GNU Finger
* and the PFinger in parallel.
*
* The same effect could be achieved with the PFinger site daemon
* but would require all clients to install the PFinger in.fingerd.
* Using of this compatibility mode allows to succesively install
* the PFinger in.fingerd.
*/
#include <config.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "finger.h"
#include "flock.h"
#include "log.h"
/* copied from GNU Finger */
/* Length of the informative items that are returned in a FINGER_PACKET. */
#define USERNAME_LEN 16
#define TTYNAME_LEN 32
#define TTYLOC_LEN 128
#define WHAT_LEN 16
/* What a packet of finger information from a client looks like. Note that
times are stored in 32 bits of SECONDS. Absolute time values are stored
as seconds since 1970. */
typedef struct {
char name[USERNAME_LEN];
char real_name[REALNAME_LEN];
char host[HOSTNAME_LEN];
time_t login_time;
time_t idle_time;
char ttyname[TTYNAME_LEN];
char ttyloc[TTYLOC_LEN];
char what[WHAT_LEN];
} FINGER_PACKET;
/* end copy */
/* read the gnufinger packets
*
* similiar to read_utmp()
*/
login_info * gnufinger_read_utmp(login_info *loginlist, int sorted)
{
FINGER_PACKET packet;
int fd;
int nread;
login_info *current, *tmp;
login_info first;
char hostdatafile[strlen(config.gnufingerdir) + 32];
time_t idlemax;
/* todo: make this an option */
idlemax = 600; /* 10min */
sprintf(hostdatafile, "%s/hostdata", config.gnufingerdir);
if ((fd = open(hostdatafile, O_RDONLY))<0) {
log(LOG_ERR, "GNU Finger mode, but could not open hostdata file: %m");
return NULL;
}
/* request a lock */
if (flock (fd, LOCK_SH) < 0) {
log(LOG_ERR, "GNU Finger mode: Lock set failed: %m");
return NULL;
}
current = &first;
current->next = loginlist;
while (current->next)
current = current->next;
/* read the packets */
while ((nread = read(fd, &packet, sizeof(packet))) == sizeof(packet)) {
/* Ignore host information packets and root account */
if ((!strlen(packet.name)) || (!strcmp(packet.name, "root")))
continue;
if (sorted) {
/* check if we already have that user */
tmp = first.next;
while(tmp) {
if (!strcmp(tmp->login_user, packet.name)) {
/* check for smallest idle time */
if (tmp->idle_time > packet.idle_time) {
tmp->idle_time = packet.idle_time;
strcpy(tmp->hostname, packet.host);
}
/* check for the earliest login time */
if (tmp->login_time > packet.login_time)
tmp->login_time = packet.login_time;
break;
}
tmp = tmp->next;
}
if (tmp)
continue;
}
/* make login info */
/* we use .login_time, .idle_time and .name */
current->next = (login_info *)malloc(sizeof(login_info));
current=current->next;
current->next = NULL;
current->login_time = packet.login_time;
current->idle_time = packet.idle_time;
strncpy(current->login_user, packet.name, UT_NAMESIZE);
strncpy(current->realname, packet.real_name, REALNAME_LEN);
current->realname[REALNAME_LEN - 1] = '\0';
strncpy(current->hostname, packet.host, HOSTNAME_LEN);
current->hostname[HOSTNAME_LEN - 1] = '\0';
current->login_user[UT_NAMESIZE - 1] = '\0';
if (current->idle_time < idlemax)
strcpy(current->status, "active");
else
strcpy(current->status, "idle");
}
close (fd);
return(first.next);
}
syntax highlighted by Code2HTML, v. 0.9.1