/*
- * The Remote User Information Daemon 1.9
+ * The Remote User Information Daemon
*
- * (c) 1997--2001 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
- *
- * This software may be freely distributed and used according to the terms
- * of the GNU General Public License. See file COPYING in any of the GNU packages.
+ * (c) 1997--2010 Martin Mares <mj@ucw.cz>
*/
#include <stdio.h>
#include <arpa/inet.h>
#include <syslog.h>
#include <sys/stat.h>
+#include <time.h>
#include <utmp.h>
#include <signal.h>
#include <dirent.h>
-#include <asm/types.h>
#include <errno.h>
#include "net.h"
struct hostrec *next;
char name[32];
time_t last_rec; /* 0=down */
- __u32 addr;
+ u32 addr;
};
static int sock, port;
{
struct hostent *h;
struct sockaddr_in sa;
- struct servent *se;
- int one;
if (name)
{
if (! (h = gethostbyname(name)))
- die("%s: %m", name);
+ die("Failed to resolve %s", name);
}
else
h = NULL;
- if (! (se = getservbyname("nwho", "udp")))
- die("Unknown service `nwho/udp'");
-
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock < 0)
die("socket: %m");
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0)
- die("setsockopt: %m");
-
sa.sin_family = AF_INET;
- sa.sin_port = port = se->s_port;
+ sa.sin_port = port = htons(NWHO_PORT);
sa.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *) &sa, sizeof(sa)) < 0)
die("bind: %m");
}
static void
-scan_utmp(struct rywho_pkt *p, time_t now)
+scan_utmp(struct nwho_pkt *p, time_t now)
{
struct utmp *u;
int cnt = 0;
sprintf(h->con, "%.7s", u->ut_line);
sprintf(device, "/dev/%s", u->ut_line);
if (stat(device, &st) < 0)
- {
- fprintf(stderr, "stat(%s): %m", device);
- continue;
- }
+ continue;
h->mesg_y = !!(S_IWGRP & st.st_mode);
last = st.st_atime;
if (st.st_mtime > last)
}
static void
-scan_load(struct rywho_pkt *p)
+scan_load(struct nwho_pkt *p)
{
int n, i, j[6];
char buf[256];
}
static void
-make_pkt(struct rywho_pkt *pkt)
+make_pkt(struct nwho_pkt *pkt)
{
bzero(pkt, sizeof(pkt));
pkt->magic = htonl(NWHO_MAGIC);
}
static void
-save_pkt(char *name, struct rywho_pkt *pkt, int len)
+save_pkt(char *name, struct nwho_pkt *pkt, int len)
{
int fd = open(name, O_WRONLY | O_CREAT, 0666);
if (fd < 0)
}
static inline int /* Validation checks not implemented yet */
-is_valid(__u32 ipa)
+is_valid(u32 ipa)
{
return 1;
}
static void
receive(void)
{
- int r, al;
- struct rywho_pkt pkt;
+ int r;
+ struct nwho_pkt pkt;
struct sockaddr_in sa;
- int n = sizeof(struct rywho_pkt) - MAX_USERS * sizeof(struct userinfo);
+ socklen_t al = sizeof(sa);
+ int n = sizeof(struct nwho_pkt) - MAX_USERS * sizeof(struct userinfo);
struct hostrec *e;
struct hostent *h;
char *c;
alarm(DEFAULT_PRUNE_TIME);
- al = sizeof(sa);
r = recvfrom(sock, &pkt, sizeof(pkt), 0, (struct sockaddr *) &sa, &al);
alarm(0);
now = time(NULL);
static void
local_scan(void)
{
- struct rywho_pkt pkt;
+ struct nwho_pkt pkt;
static char hostname[64];
make_pkt(&pkt);
}
}
+static void
+daemonize(void)
+{
+ pid_t pid = fork();
+ if (pid < 0)
+ die("Fork failed: %m");
+ if (pid)
+ exit(0);
+
+ close(0);
+ close(1);
+ close(2);
+ open("/dev/null", O_RDONLY);
+ dup(0);
+ dup(0);
+ setsid();
+}
+
static void
tick(int unused)
{
if (chdir(NWHO_SPOOL_DIR) < 0)
die("chdir(" NWHO_SPOOL_DIR "): %m");
cleanup();
+ daemonize();
bzero(&sigact, sizeof(sigact));
sigact.sa_handler = tick;
sigaction(SIGALRM, &sigact, NULL);
static void
client(char *serv)
{
- struct rywho_pkt pkt;
+ struct nwho_pkt pkt;
net_init(serv);
utmpname(UTMP_FILE);
+ daemonize();
for(;;)
{
now = time(NULL);
int
main(int argc, char **argv)
{
- int pid;
-
- if (argc != 1 && argc != 2)
- {
- fprintf(stderr, "Usage: nwhod [<server>]\n");
- return 1;
- }
- pid = fork();
- if (pid < 0)
- {
- perror("fork");
- return 1;
- }
- if (pid)
- return 0;
if (argc == 2)
client(argv[1]);
else if (argc == 1)
server();
- return 1;
+ else
+ {
+ fprintf(stderr, "Usage: nwhod [<server>]\n");
+ return 1;
+ }
+ return 0;
}