/** * Walk in directoty like "/proc/123/fd/" */ void prg_cache_load_sub(DIR * dir, const char *path_process, const char *path_fd) { char path[PATH_MAX]; char lname[30]; char finbuf[PROGNAME_WIDTH]; unsigned long inode; struct dirent *file; while ((file = readdir(dir)) != NULL) { #ifdef HAVE_STRUCT_DIRENT_D_TYPE if (file->d_type != DT_LNK) continue; #endif /* read link of "/proc/123/fd/FILENAME" */ if (!secure_snprintf (path, sizeof(path), "%s/%s", path_fd, file->d_name)) continue; if (!secure_readlink(path, lname, sizeof(lname))) continue; /* * extract inode number from name like "socket:[12345]" * or "[0000]:12345" */ if (extract_type_1_socket_inode(lname, &inode) < 0) if (extract_type_2_socket_inode(lname, &inode) < 0) continue; /* get exec fullpath */ if (!secure_snprintf (path, sizeof(path), "%s/exe", path_process)) continue; if (!secure_readlink(path, finbuf, sizeof(finbuf))) continue; /* add item to the cache */ prg_cache_add(inode, finbuf); } }
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]; long inode; const char *cs,*cmdlp; DIR *dirproc=NULL,*dirfd=NULL; struct dirent *direproc,*direfd; if (prg_cache_loaded) return; prg_cache_loaded=1; cmdlbuf[sizeof(cmdlbuf)-1]='\0'; if (!(dirproc=opendir(PATH_PROC))) goto fail; while (errno=0,direproc=readdir(dirproc)) { for (cs=direproc->d_name;*cs;cs++) if (!isdigit(*cs)) break; if (*cs) continue; procfdlen=snprintf(line,sizeof(line),PATH_PROC_X_FD,direproc->d_name); if (procfdlen<=0 || procfdlen>=sizeof(line)-5) continue; errno=0; dirfd=opendir(line); if (! dirfd) { if (errno==EACCES) eacces=1; continue; } line[procfdlen] = '/'; cmdlp = NULL; while ((direfd = readdir(dirfd))) { if (procfdlen+1+strlen(direfd->d_name)+1>sizeof(line)) continue; memcpy(line + procfdlen - PATH_FD_SUFFl, PATH_FD_SUFF "/", PATH_FD_SUFFl+1); strcpy(line + procfdlen + 1, direfd->d_name); lnamelen=readlink(line,lname,sizeof(lname)-1); lname[lnamelen] = '\0'; /*make it a null-terminated string*/ extract_type_1_socket_inode(lname, &inode); if (inode < 0) extract_type_2_socket_inode(lname, &inode); 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); prg_cache_add(inode, finbuf); } closedir(dirfd); dirfd = NULL; } if (dirproc) closedir(dirproc); if (dirfd) closedir(dirfd); if (!eacces) return; if (prg_cache_loaded == 1) { fail: fprintf(stderr,"(No info could be read for \"-p\": geteuid()=%d but you should be root.)\n", geteuid()); } else fprintf(stderr, "(Not all processes could be identified, non-owned process info\n" " will not be shown, you would have to be root to see it all.)\n"); }