update
[unix-history] / usr / src / usr.sbin / rwhod / rwhod.c
index 50351df..4f2a205 100644 (file)
@@ -11,7 +11,7 @@ char copyright[] =
 #endif not lint
 
 #ifndef lint
 #endif not lint
 
 #ifndef lint
-static char sccsid[] = "@(#)rwhod.c    5.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)rwhod.c    5.9 (Berkeley) %G%";
 #endif not lint
 
 #include <sys/types.h>
 #endif not lint
 
 #include <sys/types.h>
@@ -31,7 +31,7 @@ static char sccsid[] = "@(#)rwhod.c   5.1 (Berkeley) %G%";
 #include <ctype.h>
 #include <netdb.h>
 #include <syslog.h>
 #include <ctype.h>
 #include <netdb.h>
 #include <syslog.h>
-#include "rwhod.h"
+#include <protocols/rwhod.h>
 
 /*
  * Alarm interval. Don't forget to change the down time check in ruptime
 
 /*
  * Alarm interval. Don't forget to change the down time check in ruptime
@@ -84,9 +84,11 @@ struct       in_addr inet_makeaddr();
 main()
 {
        struct sockaddr_in from;
 main()
 {
        struct sockaddr_in from;
+       struct stat st;
        char path[64];
        char path[64];
-       int addr, on = 1;
-       struct hostent *hp;
+       int on = 1;
+       char *cp;
+       extern char *index();
 
        if (getuid()) {
                fprintf(stderr, "rwhod: not super user\n");
 
        if (getuid()) {
                fprintf(stderr, "rwhod: not super user\n");
@@ -113,9 +115,12 @@ main()
          }
        }
 #endif
          }
        }
 #endif
-       (void) chdir("/dev");
+       if (chdir(RWHODIR) < 0) {
+               perror(RWHODIR);
+               exit(1);
+       }
        (void) signal(SIGHUP, getkmem);
        (void) signal(SIGHUP, getkmem);
-       openlog("rwhod", LOG_PID, 0);
+       openlog("rwhod", LOG_PID, LOG_DAEMON);
        /*
         * Establish host name as returned by system.
         */
        /*
         * Establish host name as returned by system.
         */
@@ -123,6 +128,8 @@ main()
                syslog(LOG_ERR, "gethostname: %m");
                exit(1);
        }
                syslog(LOG_ERR, "gethostname: %m");
                exit(1);
        }
+       if ((cp = index(myname, '.')) != NULL)
+               *cp = '\0';
        strncpy(mywd.wd_hostname, myname, sizeof (myname) - 1);
        utmpf = open("/etc/utmp", O_RDONLY);
        if (utmpf < 0) {
        strncpy(mywd.wd_hostname, myname, sizeof (myname) - 1);
        utmpf = open("/etc/utmp", O_RDONLY);
        if (utmpf < 0) {
@@ -142,12 +149,6 @@ main()
                syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
                exit(1);
        }
                syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
                exit(1);
        }
-       hp = gethostbyname(myname);
-       if (hp == NULL) {
-               syslog(LOG_ERR, "%s: don't know my own name", myname);
-               exit(1);
-       }
-       sin.sin_family = hp->h_addrtype;
        sin.sin_port = sp->s_port;
        if (bind(s, &sin, sizeof (sin)) < 0) {
                syslog(LOG_ERR, "bind: %m");
        sin.sin_port = sp->s_port;
        if (bind(s, &sin, sizeof (sin)) < 0) {
                syslog(LOG_ERR, "bind: %m");
@@ -189,8 +190,12 @@ main()
                                from.sin_addr);
                        continue;
                }
                                from.sin_addr);
                        continue;
                }
-               (void) sprintf(path, "%s/whod.%s", RWHODIR, wd.wd_hostname);
-               whod = creat(path, 0666);
+               (void) sprintf(path, "whod.%s", wd.wd_hostname);
+               /*
+                * Rather than truncating and growing the file each time,
+                * use ftruncate if size is less than previous size.
+                */
+               whod = open(path, O_WRONLY | O_CREAT, 0644);
                if (whod < 0) {
                        syslog(LOG_WARNING, "%s: %m", path);
                        continue;
                if (whod < 0) {
                        syslog(LOG_WARNING, "%s: %m", path);
                        continue;
@@ -216,6 +221,8 @@ main()
 #endif
                (void) time(&wd.wd_recvtime);
                (void) write(whod, (char *)&wd, cc);
 #endif
                (void) time(&wd.wd_recvtime);
                (void) write(whod, (char *)&wd, cc);
+               if (fstat(whod, &st) < 0 || st.st_size > cc)
+                       ftruncate(whod, cc);
                (void) close(whod);
        }
 }
                (void) close(whod);
        }
 }
@@ -293,6 +300,16 @@ onalrm()
                        }
                utmpent = we - mywd.wd_we;
        }
                        }
                utmpent = we - mywd.wd_we;
        }
+
+       /*
+        * The test on utmpent looks silly---after all, if no one is
+        * logged on, why worry about efficiency?---but is useful on
+        * (e.g.) compute servers.
+        */
+       if (utmpent && chdir("/dev")) {
+               syslog(LOG_ERR, "chdir(/dev): %m");
+               exit(1);
+       }
        we = mywd.wd_we;
        for (i = 0; i < utmpent; i++) {
                if (stat(we->we_utmp.out_line, &stb) >= 0)
        we = mywd.wd_we;
        for (i = 0; i < utmpent; i++) {
                if (stat(we->we_utmp.out_line, &stb) >= 0)
@@ -310,13 +327,16 @@ onalrm()
        for (np = neighbors; np != NULL; np = np->n_next)
                (void) sendto(s, (char *)&mywd, cc, 0,
                        np->n_addr, np->n_addrlen);
        for (np = neighbors; np != NULL; np = np->n_next)
                (void) sendto(s, (char *)&mywd, cc, 0,
                        np->n_addr, np->n_addrlen);
+       if (utmpent && chdir(RWHODIR)) {
+               syslog(LOG_ERR, "chdir(%s): %m", RWHODIR);
+               exit(1);
+       }
 done:
        (void) alarm(AL_INTERVAL);
 }
 
 getkmem()
 {
 done:
        (void) alarm(AL_INTERVAL);
 }
 
 getkmem()
 {
-       struct nlist *nlp;
        static ino_t vmunixino;
        static time_t vmunixctime;
        struct stat sb;
        static ino_t vmunixino;
        static time_t vmunixctime;
        struct stat sb;
@@ -435,32 +455,6 @@ configure(s)
        return (1);
 }
 
        return (1);
 }
 
-/*
- * Return the possible subnetwork number from an internet address.
- * If the address is of the form of a subnet address (most significant
- * bit of the host part is set), believe the subnet exists.
- * Otherwise, return the network number.  Any subnet number is only valid
- * if this is a ``local'' net.
- */
-inet_subnetof(in)
-       struct in_addr in;
-{
-       register u_long i = ntohl(in.s_addr);
-
-       if (IN_CLASSA(i)) {
-               if (IN_SUBNETA(i))
-                       return ((i & IN_CLASSA_SUBNET) >> IN_CLASSA_SUBNSHIFT);
-               else
-                       return ((i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
-       } else if (IN_CLASSB(i)) {
-               if (IN_SUBNETB(i))
-                       return ((i & IN_CLASSB_SUBNET) >> IN_CLASSB_SUBNSHIFT);
-               else
-                       return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
-       } else
-               return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
-}
-
 #ifdef DEBUG
 sendto(s, buf, cc, flags, to, tolen)
        int s;
 #ifdef DEBUG
 sendto(s, buf, cc, flags, to, tolen)
        int s;