--- 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;