2 * Copyright 2004-2005 Timo Hirvonen
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 #include <tabexp_file.h>
27 #include <sys/types.h>
33 static char *get_home(const char *user
)
35 struct passwd
*passwd
;
40 passwd
= getpwuid(getuid());
42 passwd
= getpwnam(user
);
46 len
= strlen(passwd
->pw_dir
);
47 home
= xnew(char, len
+ 2);
48 memcpy(home
, passwd
->pw_dir
, len
);
54 static char *get_full_dir_name(const char *dir
)
60 } else if (dir
[0] == '~') {
61 char *first_slash
, *tmp
, *home
;
63 first_slash
= strchr(dir
, '/');
64 tmp
= xstrndup(dir
, first_slash
- dir
);
65 home
= get_home(tmp
+ 1);
69 full
= xstrjoin(home
, first_slash
);
77 static const char *starting_with
;
79 static int name_filter(const char *name
)
81 int len
= strlen(starting_with
);
87 if (strncmp(name
, starting_with
, len
))
93 static int (*user_filter
)(const char *name
, const struct stat
*s
);
95 static int load_dir_filter(const char *name
, const struct stat
*s
)
97 return name_filter(name
) && user_filter(name
, s
);
101 * load all directory entries from directory 'dir' starting with 'start' and
102 * filtered with 'filter'
104 static void tabexp_load_dir(const char *dir
, const char *start
)
110 /* for name_filter() */
111 starting_with
= start
;
113 /* tabexp is resetted */
114 full_dir_name
= get_full_dir_name(dir
);
115 if (full_dir_name
== NULL
)
118 count
= load_dir(full_dir_name
, &names
, load_dir_filter
, strptrcmp
);
121 /* opendir failed or no matches */
125 tabexp
.head
= xstrdup(dir
);
126 tabexp
.tails
= names
;
127 tabexp
.nr_tails
= count
;
130 void expand_files_and_dirs(const char *src
,
131 int (*filter
)(const char *name
, const struct stat
*s
))
135 /* for load_dir_filter() */
136 user_filter
= filter
;
138 /* split src to dir and file */
139 slash
= strrchr(src
, '/');
145 dir
= xstrndup(src
, slash
- src
+ 1);
147 /* get all dentries starting with file from dir */
148 tabexp_load_dir(dir
, file
);
152 char *home
= get_home(src
+ 1);
155 tabexp
.head
= xstrdup("");
157 tabexp
.tails
= xnew(char *, 2);
158 tabexp
.tails
[0] = home
;
159 tabexp
.tails
[1] = NULL
;
162 tabexp_load_dir("", src
);