/*Copyright (C) 2007 Matteo Lucarelli * *This program is free software; you can redistribute it and/or *modify it under the terms of the GNU General Public License *as published by the Free Software Foundation; either version 2 *of the License, or (at your option) any later version. * *This program is distributed in the hope that it will be useful, *but WITHOUT ANY WARRANTY; without even the implied warranty of *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *GNU General Public License for more details. * *You should have received a copy of the GNU General Public License *along with this program; if not, write to the Free Software *Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ******************************************************************************/ // procutils are small functions to parse proc directory under linux // getpidlist: read the list of running process ids // getbinname: from the pid obtains the binary name // getcmdline: read the command line for a running pid // parsebinname: extract the binary name from command line // parsecmdline: parse the command line in single string args // getworkingdir: get the absolute working directory of pid (even if chrooted) // getstdstream: get the standard streams opened by the process #include <stdlib.h> #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> // get the running pid list // return the count - 0 on error // // pid_t pidlist[256]; // int count = getpidlist(pidlist, 256); // int getpidlist(pid_t *pidlist, int maxcount) { int count=0; DIR* pdir=opendir("/proc/"); if (!pdir) return 0; struct dirent *ep; while ((ep=readdir(pdir))&&(count<maxcount)){ pidlist[count]=(pid_t)atol(ep->d_name); if (pidlist[count]!=0) count++; } return count; } // get the complete cmdline (not a string!) // return the size - 0 on error // // char cmdline[1024]; // size_t size=getcmdline(xxxx,cmdline,1024); // size_t getcmdline(pid_t pid, char* cmdline, size_t maxdim) { int fd; char tmp[maxdim]; size_t lenght; char* start; memset(cmdline,0,maxdim); snprintf(tmp,maxdim,"/proc/%i/cmdline",(int)pid); if ((fd=open(tmp,O_RDONLY))==0) return 0; lenght=read(fd,tmp,maxdim); close(fd); memcpy(cmdline,tmp,lenght); return lenght; } // get the binary name (as string) corresponding to pid // return the lenght of name on success, 0 on error // // char binname[128]; // size_t size = getbinname(xxxx,binname,128); // size_t getbinname(pid_t pid, char *name, int namedim) { int fd; char tmp[namedim]; size_t lenght; char* start; snprintf(tmp,namedim,"/proc/%i/cmdline",(int)pid); if ((fd=open(tmp,O_RDONLY))==0) return 0; lenght=read(fd,tmp,namedim); close(fd); if (lenght==0) return 0; start = strrchr(tmp,'/'); if (start) strncpy(name,start+1,namedim); else strncpy(name,tmp,namedim); return (strlen(name)); } // parse binary name (as string) from command line // return the size - 0 on error // // char cmdline[1024]; // char binname[128]; // if (getcmdline(xxxx,cmdline,1024)) // parsebinname(cmdline,binname,128); // size_t parsebinname(char* cmdline, char* binname, size_t maxdim) { char* start=strrchr(cmdline,'/'); if (start) strncpy(binname,start+1,maxdim); else strncpy(binname,cmdline,maxdim); return (strlen(binname)); } // parse command line in single strings // return the size - 0 on error // // char cmdline[1024]; // char* argv[128]; // size_t cmdlinedim; // int argc; // if (cmdlinedim=getcmdline(xxxx,cmdline,1024)) // argc=parsecmdline(cmdline,cmdlinedim,argv,128); // int parsecmdline(char *cmdline, size_t cmdlinedim, char **argv, int maxarg) { int argc=0; char* start=cmdline; while ((cmdline-start)<cmdlinedim && argc<maxarg){ argv[argc]=cmdline; cmdline+=strlen(argv[argc])+1; argc++; } return argc; } // get the absolute working directory of pid // // char wdir[1024]; // size_t size=getworkingdir(xxxx,wdir,1024); // size_t getworkingdir(pid_t pid, char* wdir, size_t wdirdim) { int fd; char tmp[wdirdim],chroot[wdirdim]; size_t tot; snprintf(tmp,wdirdim,"/proc/%i/root",(int)pid); readlink(tmp,chroot,wdirdim); if (!strcmp(chroot,"/")){ *chroot=0; tot=0; }else tot=strlen(chroot); snprintf(tmp,wdirdim,"/proc/%i/cwd",(int)pid); readlink(tmp,wdir,wdirdim); tot+=strlen(wdir); strncat(chroot,wdir,wdirdim); return (tot); } // get the standard streams (0:in ,1:out , 2:err) of pid // string returned can be path or symbolyc (pipe:..., socket:...) // pass NULL if some streams don't care // return the number of streams readed (0 on error) // // char pin[1024]; // char pout[1024]; // char perr[1024]; // getstdstream(xxxx,pin,pout,perr,1024); // int getstdstream(pid_t pid, char* pin, char* pout, char* perr, size_t maxchar) { int count=0; char tmp[256]; if (pin){ memset(pin,0,maxchar); snprintf(tmp,256,"/proc/%i/fd/0",(int)pid); if (readlink(tmp,pin,maxchar-1)!=-1) count++; } if (pout){ memset(pout,0,maxchar); snprintf(tmp,256,"/proc/%i/fd/1",(int)pid); if (readlink(tmp,pout,maxchar-1)!=-1) count++; } if (perr){ memset(perr,0,maxchar); snprintf(tmp,256,"/proc/%i/fd/2",(int)pid); if (readlink(tmp,perr,maxchar-1)!=-1) count++; } return count; }