1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
/* $Id: rglob.c,v 1.8 2004/05/20 11:10:52 mhe Exp $
*
* rglob.c -- remote glob functions
*
* Yet Another FTP Client
* Copyright (C) 1998-2001, Martin Hedenfalk <mhe@stacken.kth.se>
*
* 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. See COPYING for more details.
*/
#include "syshdr.h"
#include "ftp.h"
#include "strq.h"
list *rglob_create(void)
{
list *gl;
gl = list_new((listfunc)rfile_destroy);
return gl;
}
void rglob_destroy(list *gl)
{
list_free(gl);
}
bool rglob_exclude_dotdirs(rfile *f)
{
return risdotdir(f);
}
static bool contains_wildcards(char *str)
{
return (strqchr(str, '*') != 0 || strqchr(str, '?') != 0
|| strqchr(str, '[') != 0 || strqchr(str, ']') != 0);
}
/* appends rglob items in list LP matching MASK
* EXCLUDE_FUNC (if not 0) is called for each fileinfo item found
* and that file is excluded if EXCLUDE_FUNC returns true
* returns 0 if successful, -1 if failure (no files found)
*
* if ignore_multiples is true, a file isn't added to the list
* if it already exists in the list
*
* any spaces or other strange characters in MASK should be backslash-quoted
*/
int rglob_glob(list *gl, const char *mask, bool cpifnomatch,
bool ignore_multiples, rglobfunc exclude_func)
{
char *path;
char *dep, *mp;
rdirectory *rdir;
listitem *lip;
rfile *fi = 0, *nfi;
char *d;
int found = 0;
path = tilde_expand_home(mask, ftp->homedir);
dep = strrchr(path, '/');
if(!dep)
dep = path;
else dep++;
mp = xstrdup(dep);
if(mp)
unquote(mp);
/* note: mp might be NULL here, treat it like mp == "*" */
/* read the directory */
d = base_dir_xptr(path);
if(!d) d = xstrdup(ftp->curdir);
else unquote(d);
rdir = ftp_get_directory(d);
free(d);
if(rdir) {
lip = rdir->files->first;
while(lip) {
fi = (rfile *)lip->data;
lip = lip->next;
/* check if the mask includes this file */
if(mp == 0 || fnmatch(mp, base_name_ptr(fi->path), 0)
!= FNM_NOMATCH)
{
bool ignore_item;
found++;
/* call the exclude function, if any, and skip file
if the function returns true
*/
if(exclude_func && exclude_func(fi))
ignore_item = true;
else
ignore_item =
(ignore_multiples &&
(list_search(gl, (listsearchfunc)rfile_search_path,
fi->path) != 0));
if(!ignore_item) {
nfi = rfile_clone(fi);
list_additem(gl, (void *)nfi);
} else
ftp_trace("ignoring file '%s'\n", fi->path);
}
}
}
if(found == 0) {
char *p;
bool ignore_item;
if(!cpifnomatch || mp == 0 || *mp == 0 || contains_wildcards(mp)) {
free(mp);
return -1;
}
p = ftp_path_absolute(path);
unquote(p);
/* disallow multiples of the same file */
ignore_item =
(ignore_multiples &&
(list_search(gl, (listsearchfunc)rfile_search_path,
p)) != 0);
if(!ignore_item) {
nfi = rfile_create();
rfile_fake(nfi, p);
list_additem(gl, (void *)nfi);
}
free(p);
}
free(mp);
free(path);
return 0;
}
/* computes the total size (in bytes) of the files in (rglob list) GL */
unsigned long long rglob_size(list *gl)
{
listitem *li;
unsigned long long size = 0;
li = gl->first;
while(li) {
size += ((rfile *)li->data)->size;
li = li->next;
}
return size;
}
/* returns number of directories in GL */
unsigned long long rglob_numdirs(list *gl)
{
listitem *li;
unsigned long long n = 0;
li = gl->first;
while(li) {
n += risdir((rfile *)li->data);
li = li->next;
}
return n;
}
|