wmi

git clone git://oldgit.suckless.org/wmi/
Log | Files | Refs | LICENSE

expander.cpp (2849B)


      1 // Copyright (c) 2003 - 2009 Anselm R Garbe <anselm@garbe.us>
      2 // See LICENSE for license details.
      3 
      4 extern "C" {
      5 #include <unistd.h>
      6 #include <stdlib.h>
      7 
      8 #include <sys/types.h>
      9 #include <dirent.h>
     10 #include <sys/stat.h>
     11 }
     12 
     13 #include "expander.h"
     14 #include "util.h"
     15 
     16 
     17 Expander::Expander(){
     18     this->key_ = "";
     19     this->path_ = "";
     20     this->rehash();
     21 }
     22 
     23 bool Expander::rehash(){
     24     string path_env;
     25     char *p_c = getenv("PATH");
     26     if (p_c != NULL) {
     27         path_env = (string)p_c;
     28     }
     29     else{
     30         return(false);
     31     }
     32     paths_ = Util::stringSplit(path_env, ":");
     33     pathExpands_ = this->read();
     34     return true;
     35 }
     36 
     37 bool Expander::queryString (string s){
     38     paths_.clear();
     39     if ((s.find('/') == string::npos) || (Util::trimL(s).substr(0,1) == ".")) {
     40         //so performing on PATH
     41         key_ = s;
     42         pathSearch_=true;
     43     }
     44     else{
     45         //we're using the given string as search-base
     46 
     47         path_ = s.substr(0, s.find_last_of('/')+1);
     48         key_= s.substr(s.find_last_of('/')+1);
     49 
     50         paths_.insert(path_);
     51         pathSearch_=false;
     52     }
     53     return(true);
     54 }
     55 
     56 set<string> Expander::expands (){
     57 
     58     set<string> *target;
     59     if (pathSearch_) {
     60         target = &pathExpands_;
     61     }
     62     else
     63     {
     64         target = &expands_;
     65         *target = this->read();
     66     }
     67 
     68     return *target;
     69 }
     70 
     71 set<string> Expander::read(){
     72     set<string> expands;
     73     DIR *dir;
     74     dirent *entry;
     75 
     76     for (set<string>::iterator iter = paths_.begin(); iter != paths_.end(); iter++){
     77         dir=opendir(iter->c_str());
     78         if (dir != NULL) {
     79             do {
     80                 entry=readdir(dir);
     81                 if (entry != NULL) {
     82                     bool expand = false;
     83                     string filename = (string)(*iter) + "/"
     84                         + (string)(entry->d_name);
     85 
     86                     /* if we're dealing with a directory, its
     87                        sufficient to have read-permission (bash
     88                        acts like this) */
     89 
     90                     struct stat Buf;
     91                     if (stat(filename.c_str(), &Buf) == 0)
     92                     {
     93                         if (S_ISDIR(Buf.st_mode)) {
     94                             expand = true;
     95                         }
     96                     }
     97                     /* this test for executability uses the real
     98                        ids (see man 2 access) and thats why may
     99                        be incorrect if wmi is s(u/g)id'd */
    100 
    101                     if (0 == access(filename.c_str(), X_OK)) {
    102                         expand = true;
    103                     }
    104 
    105                     if (expand == true) {
    106                         expands.insert((string)(entry->d_name));
    107                     }
    108                 }
    109             } while (entry != NULL);
    110             closedir(dir);
    111         }
    112     }
    113     expands.erase(".");
    114     expands.erase("..");
    115     return(expands);
    116 }