#include #include #include #include #include #include #include #include #include "status.m" static HELP_FILE help_open ("status","openfiles"); class DEVINFO: public ARRAY_OBJ{ public: int mountlen; SSTRING mount; /*~PROTOBEG~ DEVINFO */ public: DEVINFO (const char *_mount); /*~PROTOEND~ DEVINFO */ }; PUBLIC DEVINFO::DEVINFO (const char *_mount) { mountlen = strlen(_mount); mount.setfrom (_mount); } typedef ARRAY_OBJS _DEVINFOS; class DEVINFOS: public _DEVINFOS{ public: /*~PROTOBEG~ DEVINFOS */ public: DEVINFOS (void); DEVINFO *locate (const char *path)const; /*~PROTOEND~ DEVINFOS */ }; static int cmp_by_mount (const ARRAY_OBJ *o1, const ARRAY_OBJ *o2) { const DEVINFO *d1 = (const DEVINFO*)o1; const DEVINFO *d2 = (const DEVINFO*)o2; return d1->mount.cmp(d2->mount); } PUBLIC DEVINFOS::DEVINFOS() { glocal DEVINFOS *devs = this; ("/proc/mounts",true); char dev[PATH_MAX],mount[PATH_MAX]; if (sscanf (line,"%s %s",dev,mount)==2 && strcmp(dev,"rootfs")!=0){ glocal.devs->add (new DEVINFO(mount)); } return 0; sort (cmp_by_mount); } PUBLIC DEVINFO *DEVINFOS::locate (const char *path) const { DEVINFO *ret = NULL; int n = getnb(); int lenfound = -1; for (int i=0; imountlen; if (len == 1) len = 0; // Special case for / if (d->mount.ncmp(path,len)==0 && (path[len] == '\0' || path[len] == '/')){ if (len > lenfound){ lenfound = len; ret = d; } } } return ret; } class FILTER{ public: SSTRING path; bool path_regex; SSTRING user; bool user_regex; SSTRING prog; bool prog_regex; DEVINFO *device; FILTER(){ path_regex = false; user_regex = false; prog_regex = false; device = NULL; } int edit (const DEVINFOS &devs) { int ret = -1; DIALOG dia; dia.settype (DIATYPE_POPUP); dia.gui_label (""); dia.gui_label(""); dia.gui_label (""); dia.gui_label(MSG_U(I_REGEX,"Regular expression")); dia.newline(); dia.newf_str (MSG_U(F_PATH,"File path"),path); dia.newf_chk ("",path_regex,""); dia.newline(); dia.newf_str (MSG_U(F_USER,"User"),user); dia.newf_chk ("",user_regex,""); dia.newline(); dia.newf_str (MSG_U(F_PROG,"Program"),prog); dia.newf_chk ("",prog_regex,""); dia.newline(); SSTRING mount; if (device != NULL) mount.setfrom (device->mount); FIELD_LIST *l = dia.newf_list (MSG_U(F_VOLUME,"In volume"),mount); l->addopt (""); for (int i=0; iaddopt (d->mount.get()); } dia.newline(); if (dia.edit (MSG_U(T_FILTER,"Open files filter") ,MSG_U(I_FILTER,"You can specialise the files presented") ,help_open) == MENU_ACCEPT){ if (mount.is_empty()){ device = NULL; }else{ device = devs.locate (mount.get()); } ret = 0; } return ret; } bool matchuser (const SSTRING &_user) const { return user.is_empty() || user.cmp(_user)==0; } bool matchvol (DEVINFO *dev) const { return device == NULL || device == dev; } bool matchpath (const SSTRING &_path) const { bool ret = true; if (path.is_filled()){ ret = false; int len = path.getlen(); const char *s = _path.get(); if (path.ncmp(s,len)==0 && (s[len] == '\0' || s[len] == '/')){ ret = true; } } return ret; } bool matchprog (const SSTRING &_prog) const { return prog.is_empty() || prog.cmp(_prog)==0; } }; enum FILETYPE{ FILETYPE_REG, FILETYPE_DIR, FILETYPE_DEV, FILETYPE_FIFO, FILETYPE_PROG, FILETYPE_MAP, FILETYPE_CWD }; class OPENFILE: public ARRAY_OBJ{ public: pid_t pid; SSTRING user; SSTRING command; int handle; FILETYPE type; DEVINFO *device; long long size; SSTRING path; bool mark; OPENFILE( const char *_command, const char *_user, pid_t _pid, FILETYPE _type, DEVINFO *_device, long long _size, const char *_path) { command.setfrom (_command); user.setfrom (_user); pid = _pid; type = _type; size = _size; path.setfrom (_path); device = _device; mark = false; } bool match (const FILTER &filter) { return filter.matchuser(user) && filter.matchvol(device) && filter.matchpath(path) && filter.matchprog(command); } }; typedef ARRAY_OBJS OPENFILES; void show_openfiles() { if (dialog_mode == DIALOG_TREE) return; glocal OPENFILES files; glocal DEVINFOS devs; glocal FILTER filter; (MSG_U(T_OPENFILES,"Open files"),"",help_open); newf_head (MSG_U(H_OPENFILES,"Command\tUser\tPid\tType\tVolume\tSize\tpath")); sortable(); sortpolicy ("aanaan"); sethdispo ("llrllr"); setbutinfo (MENU_USR1,MSG_U(B_RELOAD,"Reload"),MSG_R(B_RELOAD)); setbutinfo (MENU_USR2,MSG_U(B_FILTER,"Filter"),MSG_R(B_FILTER)); if (glocal.files.getnb()==0){ ("lsof","-n",20); if (noline > 0){ SSTRINGS tb; if (str_splitline (line,' ',tb)>=9){ const char *command = tb.getitem(0)->get(); pid_t pid = tb.getitem(1)->getval(); const char *user = tb.getitem(2)->get(); const char *fdstr = tb.getitem(3)->get(); const char *typestr = tb.getitem(4)->get(); if (stricmp(typestr,"IPv4")!=0){ FILETYPE type = FILETYPE_REG; if (stricmp(fdstr,"mem")==0){ type = FILETYPE_MAP; }else if (stricmp(fdstr,"txt")==0){ type = FILETYPE_PROG; }else if (stricmp(fdstr,"cwd")==0){ type = FILETYPE_CWD; }else if (stricmp(typestr,"DIR")==0){ type = FILETYPE_DIR; }else if (stricmp(typestr,"FIFO")==0){ type = FILETYPE_FIFO; }else if (stricmp(typestr,"CHR")==0 || stricmp(typestr,"BLK")==0){ type = FILETYPE_DEV; } const char *path = tb.getitem(8)->get(); DEVINFO *d = glocal.devs.locate (path); long long size = tb.getitem(6)->getval(); OPENFILE *f = new OPENFILE (command,user,pid ,type,d,size,path); glocal.files.add (f); } } } return 0; } for (int i=0; imatch(glocal.filter)){ static const char *tbtype[]={ MSG_U(I_TYPE_REG,"File"), MSG_U(I_TYPE_DIR,"Dir."), MSG_U(I_TYPE_DEV,"Dev."), MSG_U(I_TYPE_FIFO,"Fifo"), MSG_U(I_TYPE_PROG,"Prog."), MSG_U(I_TYPE_MAP,"Lib."), MSG_U(I_TYPE_CWD,"Cwd"), }; DEVINFO *d = f->device; const char *mount = d == NULL ? "" : d->mount.get(); if (f->mark) setnexttagged (); new_menuitemf (f->command.get() ,"%s\t%u\t%s\t%s\t%Ld\t%s" ,f->user.get() ,f->pid,tbtype[f->type] ,mount,f->size ,f->path.get()); } } if (code == MENU_USR1){ glocal.files.remove_all(); }else if (code == MENU_USR2){ glocal.filter.edit (glocal.devs); } OPENFILE *f = glocal.files.getitem(no); if (uistate.shiftkey){ f->mark = !f->mark; }else{ DIALOG_MENUPOPUP dia; dia.new_menuitem ("",MSG_R(M_KILL)); int nof = 0; if (dia.editmenu ("",nof)== MENU_OK){ if (nof == 0){ } } } }