--- wminet.c.orig	Fri Dec 18 06:07:27 1998
+++ wminet.c	Thu Aug 16 11:08:44 2001
@@ -10,6 +10,8 @@
 
  ProFTPD support by Mike Kershaw aka Dragorn (dragorn@melchior.nerv-un.ml.org)
  ProFTPD support was made 64bit clean by Martijn Pieterse (pieterse@xs4all.nl)
+
+ FreeBSD port by Stephen Kiernan (sk-ports@vegamuse.org)
  
  see http://windowmaker.mezaway.org for more awesome wm dock apps :)
 
@@ -23,6 +25,11 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <ctype.h>
+#ifdef __FreeBSD__
+#include <limits.h>
+#include <kvm.h>
+#include <netdb.h>
+#endif /* __FreeBSD__ */
 
 #include <sys/wait.h>
 #include <sys/stat.h>
@@ -30,6 +37,23 @@
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
+#ifdef __FreeBSD__
+#include <sys/socketvar.h>
+#include <sys/sysctl.h>
+
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+
+#include <arpa/inet.h>
+#endif /* __FreeBSD__ */
 
 #include <utmp.h>
 #include <dirent.h>
@@ -57,6 +81,10 @@
 // Lame work-around... Sigh... when will they standardize the headers!?!?
 #define TCP_ESTABLISHED 1
 
+#ifndef DEFAULT_WMINETRC
+#define DEFAULT_WMINETRC "/etc/wminetrc"
+#endif /* DEFAULT_WMINETRC */
+
 extern	char **environ;
 
 char	*ProgName;
@@ -101,6 +129,13 @@
 
 char uconfig_file[256];
 
+#ifdef __FreeBSD__
+struct utmp *_wminet_getutent(FILE *);
+#define setutent() { FILE *_wminet__ufp = fopen(_PATH_UTMP, "r")
+#define getutent() _wminet_getutent(_wminet__ufp)
+#define endutent() fclose(_wminet__ufp); }
+#endif /* __FreeBSD__ */
+
 void usage(void);
 void printversion(void);
 void BlitString(char *name, int x, int y);
@@ -109,10 +144,22 @@
 void wminet_routine(int, char **);
 int PortWatch( short port );
 int ReadConfigInt(FILE *fp, char *setting, int *value);
-int ReadConfigString(FILE *fp, char *setting, char *value);
+int ReadConfigString(FILE *fp, char *setting, char *value, int len);
 int Read_Config_File( char *filename );
 
 
+#ifdef __FreeBSD__
+inline
+struct utmp *_wminet_getutent( FILE *fp )
+{
+   static struct utmp usr;
+   if( fread((char *)&usr, sizeof(usr), 1, fp) == 1 )
+      return &usr;
+   else
+      return NULL;
+}
+#endif /* __FreeBSD__ */
+
 int main(int argc, char *argv[]) {
 
 	int		i;
@@ -149,7 +196,7 @@
             case 'c' :
                 if (argc > (i+1))
                 {
-                    strcpy(uconfig_file, argv[i+1]);
+                    strncpy(uconfig_file, argv[i+1], 256);
                     i++;
                 }
                 break;
@@ -214,12 +261,12 @@
     }
     else
     {
-        sprintf(config_file, "%s/.wminetrc", getenv("HOME"));
+        snprintf(config_file, 256, "%s/.wminetrc", getenv("HOME"));
 
         if (!Read_Config_File(config_file))
         {
             // Fall back to /etc/wminetrc
-            sprintf(config_file, "/etc/wminetrc");
+            snprintf(config_file, 256, DEFAULT_WMINETRC);
         
             Read_Config_File(config_file);
         }
@@ -240,13 +287,13 @@
                 if (use_proftpd)
                 {
                     if (strstr(dent->d_name, "proftpd-") != NULL)
-                        strcpy(ftpclasses[0], dent->d_name);
+                        strncpy(ftpclasses[0], dent->d_name, 64);
                 }
                 else
                 {
                     if (strstr(dent->d_name, "ftp.pids-") != NULL)
                     {
-                        strcpy(ftpclasses[numftpclasses++], dent->d_name);
+                        strncpy(ftpclasses[numftpclasses++], dent->d_name, 64);
                         //printf("ftppidfile: %s\n", dent->d_name);
                     }
                 }
@@ -422,7 +469,6 @@
     char seps[]={"/"};
     char sep2[]={":"};
     char sep3[]={" "};
-
 #ifdef HTTP_MONITOR_PROC
     DIR *dir;
     struct dirent *dent;
@@ -439,8 +485,13 @@
         setutent();
         while ((ut = getutent()))
         {
-            if ((ut->ut_type == USER_PROCESS) && 
-		(ut->ut_name[0] != '\0'))
+            if (
+#ifdef __FreeBSD__
+                (ut->ut_line[0] != '\0')
+#else
+                (ut->ut_type == USER_PROCESS)
+#endif /* __FreeBSD__ */
+		&& (ut->ut_name[0] != '\0'))
             {
                 nUsers++;
             }
@@ -459,7 +510,7 @@
             logrun_t runent;
             logrun_header_t head;
 
-            sprintf(buf, "%s/%s", ftp_pid_path, ftpclasses[0]);
+            snprintf(buf, 1024, "%s/%s", ftp_pid_path, ftpclasses[0]);
 
             if (( fd = open(buf, O_RDONLY, 0644)) == -1)
             {
@@ -486,7 +537,7 @@
         } else {
             for (i=0; i!= numftpclasses; i++)
             {
-                sprintf(buf, "%s/%s", ftp_pid_path, ftpclasses[i]);
+                snprintf(buf, 1024, "%s/%s", ftp_pid_path, ftpclasses[i]);
                 //printf("opening '%s'\n", buf);
                 fp = fopen(buf, "r");
                 if (fp)
@@ -508,11 +559,10 @@
     // httpd processes
     nHttp = 0;
 
-#ifdef HTTP_MONITOR_PROC
+#if defined(HTTP_MONITOR_PROC) && !defined(__FreeBSD__)
 
     if ( monitor_http )
     {
-
         dir = opendir("/proc");
         if (dir)
         {
@@ -520,7 +570,7 @@
             {
                 if (!isalpha(dent->d_name[0]))
                 {
-                    sprintf(buf, "/proc/%s/stat", dent->d_name);
+                    snprintf(buf, 1024, "/proc/%s/stat", dent->d_name);
                     //printf("opening '%s'\n", buf);
                     fp=fopen(buf, "r");
                     if (fp)
@@ -544,41 +594,7 @@
 #ifdef HTTP_MONITOR_NET
 
     if ( monitor_http )
-    {
-
-        fp = fopen("/proc/net/tcp", "r");
-        if (fp)
-        {
-            fgets(buf, 512, fp); // get rid of text header
-    
-            while ( (fgets(buf, 512, fp)) )
-            {
-                tok = strtok(buf, sep2);
-                tok = strtok(NULL, sep2);
-                tok = strtok(NULL, sep2);
-    
-                tok[4]=0;
-				tok1 = strtok(NULL, sep2);
-				tok1 += 5;
-				tok1[2] = 0;
-    
-                // printf("port: %i\n", strtol(tok, NULL, 16));
-				// printf("state: %i\n", strtol(tok1, NULL, 16));
-    
-                i = strtol(tok, NULL, 16);
-				j = strtol(tok1, NULL, 16);
-    
-                // should make this configurable
-                if (( i == 80  || i == 8080) && (j == TCP_ESTABLISHED))
-                {
-                    nHttp++;
-                }
-    
-            }
-    
-            fclose(fp);
-        }
-    }
+        nHttp = PortWatch( 80 ) + PortWatch( 8080 );
 #endif
 
 
@@ -587,7 +603,11 @@
 
     if ( monitor_nfs )
     {
+#ifdef __FreeBSD__
+        fp = popen("/usr/bin/showmount -a", "r");
+#else
         fp = popen("/usr/sbin/showmount -a", "r");
+#endif /* __FreeBSD__ */
         if (fp)
         {
             while ( (fgets(buf, 128, fp)) )
@@ -604,9 +624,46 @@
     // Total Processes
     nProc = 0;
 
+#if defined(__FreeBSD__) && defined(HTTP_MONITOR_PROC)
+    if( monitor_proc || monitor_http )
+#else
     if ( monitor_proc )
+#endif /* __FreeBSD__ && HTTP_MONITOR_PROC */
     {
-        
+#ifdef __FreeBSD__
+        char errbuf[_POSIX2_LINE_MAX];
+        kvm_t *kd = kvm_openfiles( NULL, NULL, NULL, O_RDONLY, errbuf );
+        if( kd == 0 )
+           fprintf( stderr, "%s", errbuf );
+        else
+        {
+           int procs;
+
+#ifdef HTTP_MONITOR_PROC
+           struct kinfo_proc *kinfo =
+#endif /* HTTP_MONITOR_PROC */
+               kvm_getprocs(kd,KERN_PROC_ALL,0,&procs);
+
+#ifdef HTTP_MONITOR_PROC
+           if( monitor_http )
+           {
+              int i;
+              for( i = 0; i < procs; i++ )
+              {
+                 if( !strncmp( KI_PROC(&kinfo[i])->p_comm, "(httpd)", 7 ) )
+                 {
+                    nHttp++;
+                 }
+              }
+           }
+#endif /* HTTP_MONITOR_PROC */
+
+           kvm_close( kd );
+
+           if( monitor_proc )
+              nProc = procs;
+        }
+#else        
         fp = fopen("/proc/loadavg", "r");
         if (fp)
         {
@@ -617,6 +674,7 @@
             
             fclose(fp);
         }
+#endif /* __FreeBSD__ */
     }
 
     // lpd
@@ -654,14 +712,61 @@
 
 int PortWatch( short port )
 {
+
+    int count=0;
+
+#ifdef __FreeBSD__
+    struct protoent *p;
+
+    setprotoent(1);
+    setservent(1);
+    while((p = getprotoent()))
+    {
+       if( !strcmp( p->p_name, "tcp" ) )
+       {
+          int len = 0;
+          if( sysctlbyname( "net.inet.tcp.pcblist", 0, &len, 0, 0 ) >= 0 )
+          {
+             char *buf = malloc(len);
+             if( buf )
+             {
+                if( sysctlbyname("net.inet.tcp.pcblist", buf, &len, 0, 0) >= 0 )
+                {
+                   struct xinpgen *xig, *oxig;
+
+                   oxig = xig = (struct xinpgen *)buf;
+                   for( xig = (struct xinpgen *)((char *)xig + xig->xig_len);
+                        xig->xig_len > sizeof(struct xinpgen);
+                        xig = (struct xinpgen *)((char *)xig + xig->xig_len))
+                   {
+                      struct tcpcb   *tp  = &((struct xtcpcb *)xig)->xt_tp;
+                      struct inpcb   *inp = &((struct xtcpcb *)xig)->xt_inp;
+                      struct xsocket *so  = &((struct xtcpcb *)xig)->xt_socket;
+
+                      if( ( so->xso_protocol != IPPROTO_TCP ) ||
+                          ( inp->inp_gencnt > oxig->xig_gen ) ||
+                          ( inet_lnaof(inp->inp_laddr) == INADDR_ANY ) )
+                        continue;
+
+                      if( ( ntohs((u_short)inp->inp_lport) == port ) &&
+                          ( tp->t_state == TCPS_ESTABLISHED ) )
+                      {
+                         count++;
+                      }
+                   }
+                }
+                free(buf);
+             }
+          }
+       }
+    }
+#else
     FILE *fp;
     char buf[1024];
     char *tok,*tok1;
     int i,j;
     char sep2[]={":"};
 
-    int count=0;
-
     fp = fopen("/proc/net/tcp", "r");
     if (fp)
     {
@@ -693,6 +798,7 @@
 
         fclose(fp);
     }
+#endif /* __FreeBSD__ */
 
     return count;
 }
@@ -745,14 +851,14 @@
         newx -= CHAR_WIDTH;
     }
 
-    sprintf(buf, "%02i", num);
+    snprintf(buf, 1024, "%02i", num);
 
     BlitString(buf, newx, y);
 }
     
 
 // ReadConfigSetting
-int ReadConfigString(FILE *fp, char *setting, char *value)
+int ReadConfigString(FILE *fp, char *setting, char *value, int vallen)
 {
     char str[1024];
     char buf[1024];
@@ -767,7 +873,7 @@
         return 0;
     }
 
-    sprintf(str, "%s=", setting);
+    snprintf(str, 1024, "%s=", setting);
     slen = strlen(str);
     
     fseek(fp, 0, SEEK_SET);
@@ -799,7 +905,7 @@
                 if ( buf[i] == '=' )
                 {
                     p=buf+i+1;
-                    strcpy(value, p);
+                    strncpy(value, p, vallen);
                     return 1;
                 }
             }
@@ -814,7 +920,7 @@
 {
     char buf[1024];
 
-    if (ReadConfigString(fp, setting, (char *) &buf))
+    if (ReadConfigString(fp, setting, (char *) &buf, 1024))
     {
         *value = atoi(buf);
         return 1;
@@ -831,11 +937,11 @@
     if (fp)
     {
         ReadConfigInt(fp, "interval", &loopinterval);
-        ReadConfigString(fp, "action1", action1);
-        ReadConfigString(fp, "action2", action2);
-        ReadConfigString(fp, "action3", action3);
-        ReadConfigString(fp, "action4", action4);
-        ReadConfigString(fp, "action5", action5);
+        ReadConfigString(fp, "action1", action1, 256);
+        ReadConfigString(fp, "action2", action2, 256);
+        ReadConfigString(fp, "action3", action3, 256);
+        ReadConfigString(fp, "action4", action4, 256);
+        ReadConfigString(fp, "action5", action5, 256);
         ReadConfigInt(fp, "monitor_proc", &monitor_proc);
         ReadConfigInt(fp, "monitor_users", &monitor_users);
         ReadConfigInt(fp, "monitor_ftp", &monitor_ftp);
@@ -843,23 +949,23 @@
         ReadConfigInt(fp, "monitor_nfs", &monitor_nfs);
         ReadConfigInt(fp, "monitor_lpd", &monitor_lpd);
         ReadConfigInt(fp, "use_proftpd", &use_proftpd);
-        ReadConfigString(fp, "ftp_pid_path", ftp_pid_path);
+        ReadConfigString(fp, "ftp_pid_path", ftp_pid_path, 256);
 
         ReadConfigInt(fp, "portwatch1.pos", &portwatch[1].pos);
         ReadConfigInt(fp, "portwatch1.port", &portwatch[1].port);
-        ReadConfigString(fp, "portwatch1.label", portwatch[1].label);
+        ReadConfigString(fp, "portwatch1.label", portwatch[1].label, 10);
         ReadConfigInt(fp, "portwatch2.pos", &portwatch[2].pos);
         ReadConfigInt(fp, "portwatch2.port", &portwatch[2].port);
-        ReadConfigString(fp, "portwatch2.label", portwatch[2].label);
+        ReadConfigString(fp, "portwatch2.label", portwatch[2].label, 10);
         ReadConfigInt(fp, "portwatch3.pos", &portwatch[3].pos);
         ReadConfigInt(fp, "portwatch3.port", &portwatch[3].port);
-        ReadConfigString(fp, "portwatch3.label", portwatch[3].label);
+        ReadConfigString(fp, "portwatch3.label", portwatch[3].label, 10);
         ReadConfigInt(fp, "portwatch4.pos", &portwatch[4].pos);
         ReadConfigInt(fp, "portwatch4.port", &portwatch[4].port);
-        ReadConfigString(fp, "portwatch4.label", portwatch[4].label);
+        ReadConfigString(fp, "portwatch4.label", portwatch[4].label, 10);
         ReadConfigInt(fp, "portwatch5.pos", &portwatch[5].pos);
         ReadConfigInt(fp, "portwatch5.port", &portwatch[5].port);
-        ReadConfigString(fp, "portwatch5.label", portwatch[5].label);
+        ReadConfigString(fp, "portwatch5.label", portwatch[5].label, 10);
         
         fclose(fp);
         return 1;