BVB Source Codes

cmus Show tabexp_file.c Source code

Return Download cmus: download tabexp_file.c Source code - Download cmus Source code - Type:.c
  1. /*
  2.  * Copyright 2008-2013 Various Authors
  3.  * Copyright 2004-2005 Timo Hirvonen
  4.  *
  5.  * This program is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU General Public License as
  7.  * published by the Free Software Foundation; either version 2 of the
  8.  * License, or (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  17.  */
  18.  
  19. #include "tabexp_file.h"
  20. #include "tabexp.h"
  21. #include "load_dir.h"
  22. #include "misc.h"
  23. #include "xmalloc.h"
  24. #include "xstrjoin.h"
  25.  
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <unistd.h>
  29. #include <pwd.h>
  30. #include <dirent.h>
  31.  
  32. static char *get_home(const char *user)
  33. {
  34.         struct passwd *passwd;
  35.         char *home;
  36.         int len;
  37.  
  38.         if (user[0] == 0) {
  39.                 passwd = getpwuid(getuid());
  40.         } else {
  41.                 passwd = getpwnam(user);
  42.         }
  43.         if (passwd == NULL)
  44.                 return NULL;
  45.         len = strlen(passwd->pw_dir);
  46.         home = xnew(char, len + 2);
  47.         memcpy(home, passwd->pw_dir, len);
  48.         home[len] = '/';
  49.         home[len + 1] = 0;
  50.         return home;
  51. }
  52.  
  53. static char *get_full_dir_name(const char *dir)
  54. {
  55.         char *full;
  56.  
  57.         if (dir[0] == 0) {
  58.                 full = xstrdup("./");
  59.         } else if (dir[0] == '~') {
  60.                 char *first_slash, *tmp, *home;
  61.  
  62.                 first_slash = strchr(dir, '/');
  63.                 tmp = xstrndup(dir, first_slash - dir);
  64.                 home = get_home(tmp + 1);
  65.                 free(tmp);
  66.                 if (home == NULL)
  67.                         return NULL;
  68.                 full = xstrjoin(home, first_slash);
  69.                 free(home);
  70.         } else {
  71.                 full = xstrdup(dir);
  72.         }
  73.         return full;
  74. }
  75.  
  76. static void load_dir(struct ptr_array *array,
  77.                 const char *dirname, const char *start,
  78.                 int (*filter)(const char *, const struct stat *))
  79. {
  80.         int start_len = strlen(start);
  81.         struct directory dir;
  82.         char *full_dir_name;
  83.         const char *name;
  84.  
  85.         full_dir_name = get_full_dir_name(dirname);
  86.         if (!full_dir_name)
  87.                 return;
  88.  
  89.         if (dir_open(&dir, full_dir_name))
  90.                 goto out;
  91.  
  92.         while ((name = dir_read(&dir))) {
  93.                 char *str;
  94.  
  95.                 if (!start_len) {
  96.                         if (name[0] == '.')
  97.                                 continue;
  98.                 } else {
  99.                         if (strncmp(name, start, start_len))
  100.                                 continue;
  101.                 }
  102.  
  103.                 if (!filter(name, &dir.st))
  104.                         continue;
  105.  
  106.                 if (S_ISDIR(dir.st.st_mode)) {
  107.                         int len = strlen(name);
  108.  
  109.                         str = xnew(char, len + 2);
  110.                         memcpy(str, name, len);
  111.                         str[len++] = '/';
  112.                         str[len] = 0;
  113.                 } else {
  114.                         str = xstrdup(name);
  115.                 }
  116.                 ptr_array_add(array, str);
  117.         }
  118.         dir_close(&dir);
  119. out:
  120.         free(full_dir_name);
  121. }
  122.  
  123. /*
  124.  * load all directory entries from directory 'dir' starting with 'start' and
  125.  * filtered with 'filter'
  126.  */
  127. static void tabexp_load_dir(const char *dirname, const char *start,
  128.                 int (*filter)(const char *, const struct stat *))
  129. {
  130.         PTR_ARRAY(array);
  131.  
  132.         /* tabexp is reseted */
  133.         load_dir(&array, dirname, start, filter);
  134.  
  135.         if (array.count) {
  136.                 ptr_array_sort(&array, strptrcmp);
  137.  
  138.                 tabexp.head = xstrdup(dirname);
  139.                 tabexp.tails = array.ptrs;
  140.                 tabexp.count = array.count;
  141.         }
  142. }
  143.  
  144. static void tabexp_load_env_path(const char *env_path, const char *start,
  145.                 int (*filter)(const char *, const struct stat *))
  146. {
  147.         char *path = xstrdup(env_path);
  148.         PTR_ARRAY(array);
  149.         char cwd[1024];
  150.         char *p = path, *n;
  151.  
  152.         /* tabexp is reseted */
  153.         do {
  154.                 n = strchr(p, ':');
  155.                 if (n)
  156.                         *n = '\0';
  157.                 if (strcmp(p, "") == 0 && getcwd(cwd, sizeof(cwd)))
  158.                         p = cwd;
  159.                 load_dir(&array, p, start, filter);
  160.                 p = n + 1;
  161.         } while (n);
  162.  
  163.         if (array.count) {
  164.                 ptr_array_sort(&array, strptrcoll);
  165.                 ptr_array_unique(&array, strptrcmp);
  166.  
  167.                 tabexp.head = xstrdup("");
  168.                 tabexp.tails = array.ptrs;
  169.                 tabexp.count = array.count;
  170.         }
  171.  
  172.         free(path);
  173. }
  174.  
  175. void expand_files_and_dirs(const char *src,
  176.                 int (*filter)(const char *name, const struct stat *s))
  177. {
  178.         char *slash;
  179.  
  180.         /* split src to dir and file */
  181.         slash = strrchr(src, '/');
  182.         if (slash) {
  183.                 char *dir;
  184.                 const char *file;
  185.  
  186.                 /* split */
  187.                 dir = xstrndup(src, slash - src + 1);
  188.                 file = slash + 1;
  189.                 /* get all dentries starting with file from dir */
  190.                 tabexp_load_dir(dir, file, filter);
  191.                 free(dir);
  192.         } else {
  193.                 if (src[0] == '~') {
  194.                         char *home = get_home(src + 1);
  195.  
  196.                         if (home) {
  197.                                 tabexp.head = xstrdup("");
  198.                                 tabexp.tails = xnew(char *, 1);
  199.                                 tabexp.tails[0] = home;
  200.                                 tabexp.count = 1;
  201.                         }
  202.                 } else {
  203.                         tabexp_load_dir("", src, filter);
  204.                 }
  205.         }
  206. }
  207.  
  208. void expand_env_path(const char *src,
  209.                 int (*filter)(const char *name, const struct stat *s))
  210. {
  211.         const char *env_path = getenv("PATH");
  212.  
  213.         if (!env_path || strcmp(env_path, "") == 0)
  214.                 return;
  215.  
  216.         tabexp_load_env_path(env_path, src, filter);
  217. }
  218.  
downloadtabexp_file.c Source code - Download cmus Source code
Related Source Codes/Software:
Ink - An HTML5/CSS3 framework used at SAPO for fast and ... 2017-04-22
memory-stats.js - minimal monitor for JS Heap Size via performance.m... 2017-04-22
LayoutKit - LayoutKit is a fast view layout library for iOS, m... 2017-04-22
Cpp-Primer - C++ Primer 5 answer 2017-04-22
RBBAnimation - Block-based animations made easy, comes with easin... 2017-04-22
phpDocumentor2 - Documentation Generator for PHP ... 2017-04-22
flexboxfroggy - A game for learning CSS flexbox ... 2017-04-22
wicked - Use wicked to turn your controller into a wizard ... 2017-04-22
Begin-Latex-in-minutes - Brief Intro to LaTeX for beginners that helps you ... 2017-04-22
guard-livereload - Guard::LiveReload automatically reload your browse... 2017-04-22
swifter - Tiny http server engine written in Swift programmi... 2017-04-29
Chartbuilder - A front-end charting application that facilitates ... 2017-04-29
offline-first - 2017-04-29
plotly.py - An interactive, browser-based graphing library for... 2017-04-29
statsmodels - Statsmodels: statistical modeling and econometrics... 2017-04-29
android-maps-utils - Handy extensions to the Google Maps Android API. 2017-04-29
enyo - A JavaScript application framework emphasizing mod... 2017-04-29
darkforestGo - DarkForest, the Facebook Go engine. 2017-04-29
erpnext - ERP made Simple http://erpn... 2017-04-29
SwiftInFlux - An attempt to gather all that is in flux in Swift. 2017-04-29

 Back to top