--- net-tools-1.60/netstat.c 2001-04-15 10:41:17.000000000 -0400 +++ net-tools-1.60/netstat-new.c 2004-04-24 14:20:27.000000000 -0400 @@ -244,8 +244,8 @@ #define PATH_FD_SUFF "fd" #define PATH_FD_SUFFl strlen(PATH_FD_SUFF) #define PATH_PROC_X_FD PATH_PROC "/%s/" PATH_FD_SUFF -#define PATH_CMDLINE "cmdline" -#define PATH_CMDLINEl strlen(PATH_CMDLINE) +#define PATH_EXE "exe" +#define PATH_EXEl strlen(PATH_EXE) /* NOT working as of glibc-2.0.7: */ #undef DIRENT_HAVE_D_TYPE_WORKS @@ -341,16 +341,15 @@ static void prg_cache_load(void) { char line[LINE_MAX],eacces=0; - int procfdlen,fd,cmdllen,lnamelen; - char lname[30],cmdlbuf[512],finbuf[PROGNAME_WIDTH]; + int procfdlen,lnamelen,lexelen; + char lname[30],lexe[30],finbuf[PROGNAME_WIDTH]; long inode; - const char *cs,*cmdlp; + const char *cs,*exep; DIR *dirproc=NULL,*dirfd=NULL; struct dirent *direproc,*direfd; if (prg_cache_loaded || !flag_prg) return; prg_cache_loaded=1; - cmdlbuf[sizeof(cmdlbuf)-1]='\0'; if (!(dirproc=opendir(PATH_PROC))) goto fail; while (errno=0,direproc=readdir(dirproc)) { #ifdef DIRENT_HAVE_D_TYPE_WORKS @@ -372,7 +371,8 @@ continue; } line[procfdlen] = '/'; - cmdlp = NULL; + + exep = NULL; while ((direfd = readdir(dirfd))) { #ifdef DIRENT_HAVE_D_TYPE_WORKS if (direfd->d_type!=DT_LNK) @@ -392,28 +392,26 @@ if (inode < 0) continue; - if (!cmdlp) { - if (procfdlen - PATH_FD_SUFFl + PATH_CMDLINEl >= - sizeof(line) - 5) - continue; - strcpy(line + procfdlen-PATH_FD_SUFFl, PATH_CMDLINE); - fd = open(line, O_RDONLY); - if (fd < 0) - continue; - cmdllen = read(fd, cmdlbuf, sizeof(cmdlbuf) - 1); - if (close(fd)) - continue; - if (cmdllen == -1) - continue; - if (cmdllen < sizeof(cmdlbuf) - 1) - cmdlbuf[cmdllen]='\0'; - if ((cmdlp = strrchr(cmdlbuf, '/'))) - cmdlp++; - else - cmdlp = cmdlbuf; - } - - snprintf(finbuf, sizeof(finbuf), "%s/%s", direproc->d_name, cmdlp); + if(!exep) + { + if (procfdlen - PATH_FD_SUFFl + PATH_EXEl >= + sizeof(line) - 5) + continue; + strcpy(line + procfdlen-PATH_FD_SUFFl, PATH_EXE); + + /* processes which modify cmdline to something containing a slash broke + the old code. (ex. "sshd: root@pts/0" would show /0 when netstat was + run with -p) we use readlink(/proc//exe) to read the actual binary name. */ + lexelen=readlink(line,lexe,sizeof(lexe)-1); + lexe[lexelen] = '\0'; + + if ((exep = strrchr(lexe, '/'))) + exep++; + else + exep = lexe; + } + + snprintf(finbuf, sizeof(finbuf), "%s/%s", direproc->d_name, exep); prg_cache_add(inode, finbuf); } closedir(dirfd);