1761efaa7SDag-Erling Smørgrav /* $OpenBSD: sftp-glob.c,v 1.22 2006/08/03 03:34:42 deraadt Exp $ */ 21e8db6e2SBrian Feldman /* 3efcad6b7SDag-Erling Smørgrav * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 41e8db6e2SBrian Feldman * 5efcad6b7SDag-Erling Smørgrav * Permission to use, copy, modify, and distribute this software for any 6efcad6b7SDag-Erling Smørgrav * purpose with or without fee is hereby granted, provided that the above 7efcad6b7SDag-Erling Smørgrav * copyright notice and this permission notice appear in all copies. 81e8db6e2SBrian Feldman * 9efcad6b7SDag-Erling Smørgrav * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10efcad6b7SDag-Erling Smørgrav * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11efcad6b7SDag-Erling Smørgrav * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12efcad6b7SDag-Erling Smørgrav * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13efcad6b7SDag-Erling Smørgrav * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14efcad6b7SDag-Erling Smørgrav * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15efcad6b7SDag-Erling Smørgrav * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 161e8db6e2SBrian Feldman */ 171e8db6e2SBrian Feldman 181e8db6e2SBrian Feldman #include "includes.h" 191e8db6e2SBrian Feldman 20761efaa7SDag-Erling Smørgrav #include <sys/types.h> 21761efaa7SDag-Erling Smørgrav #ifdef HAVE_SYS_STAT_H 22761efaa7SDag-Erling Smørgrav # include <sys/stat.h> 23761efaa7SDag-Erling Smørgrav #endif 24761efaa7SDag-Erling Smørgrav 25761efaa7SDag-Erling Smørgrav #include <dirent.h> 26761efaa7SDag-Erling Smørgrav #include <string.h> 27761efaa7SDag-Erling Smørgrav 281e8db6e2SBrian Feldman #include "xmalloc.h" 291e8db6e2SBrian Feldman #include "sftp.h" 30761efaa7SDag-Erling Smørgrav #include "buffer.h" 311e8db6e2SBrian Feldman #include "sftp-common.h" 321e8db6e2SBrian Feldman #include "sftp-client.h" 33efcad6b7SDag-Erling Smørgrav 34efcad6b7SDag-Erling Smørgrav int remote_glob(struct sftp_conn *, const char *, int, 35efcad6b7SDag-Erling Smørgrav int (*)(const char *, int), glob_t *); 361e8db6e2SBrian Feldman 371e8db6e2SBrian Feldman struct SFTP_OPENDIR { 381e8db6e2SBrian Feldman SFTP_DIRENT **dir; 391e8db6e2SBrian Feldman int offset; 401e8db6e2SBrian Feldman }; 411e8db6e2SBrian Feldman 421e8db6e2SBrian Feldman static struct { 43ae1f160dSDag-Erling Smørgrav struct sftp_conn *conn; 441e8db6e2SBrian Feldman } cur; 451e8db6e2SBrian Feldman 46ae1f160dSDag-Erling Smørgrav static void * 47ae1f160dSDag-Erling Smørgrav fudge_opendir(const char *path) 481e8db6e2SBrian Feldman { 491e8db6e2SBrian Feldman struct SFTP_OPENDIR *r; 501e8db6e2SBrian Feldman 511e8db6e2SBrian Feldman r = xmalloc(sizeof(*r)); 521e8db6e2SBrian Feldman 534b17dab0SDag-Erling Smørgrav if (do_readdir(cur.conn, (char *)path, &r->dir)) { 544b17dab0SDag-Erling Smørgrav xfree(r); 551e8db6e2SBrian Feldman return(NULL); 564b17dab0SDag-Erling Smørgrav } 571e8db6e2SBrian Feldman 581e8db6e2SBrian Feldman r->offset = 0; 591e8db6e2SBrian Feldman 601e8db6e2SBrian Feldman return((void *)r); 611e8db6e2SBrian Feldman } 621e8db6e2SBrian Feldman 63ae1f160dSDag-Erling Smørgrav static struct dirent * 64ae1f160dSDag-Erling Smørgrav fudge_readdir(struct SFTP_OPENDIR *od) 651e8db6e2SBrian Feldman { 6683d2307dSDag-Erling Smørgrav /* Solaris needs sizeof(dirent) + path length (see below) */ 6783d2307dSDag-Erling Smørgrav static char buf[sizeof(struct dirent) + MAXPATHLEN]; 6883d2307dSDag-Erling Smørgrav struct dirent *ret = (struct dirent *)buf; 6983d2307dSDag-Erling Smørgrav #ifdef __GNU_LIBRARY__ 7083d2307dSDag-Erling Smørgrav static int inum = 1; 7183d2307dSDag-Erling Smørgrav #endif /* __GNU_LIBRARY__ */ 721e8db6e2SBrian Feldman 731e8db6e2SBrian Feldman if (od->dir[od->offset] == NULL) 741e8db6e2SBrian Feldman return(NULL); 751e8db6e2SBrian Feldman 7683d2307dSDag-Erling Smørgrav memset(buf, 0, sizeof(buf)); 771e8db6e2SBrian Feldman 7883d2307dSDag-Erling Smørgrav /* 7983d2307dSDag-Erling Smørgrav * Solaris defines dirent->d_name as a one byte array and expects 8083d2307dSDag-Erling Smørgrav * you to hack around it. 8183d2307dSDag-Erling Smørgrav */ 8283d2307dSDag-Erling Smørgrav #ifdef BROKEN_ONE_BYTE_DIRENT_D_NAME 8383d2307dSDag-Erling Smørgrav strlcpy(ret->d_name, od->dir[od->offset++]->filename, MAXPATHLEN); 8483d2307dSDag-Erling Smørgrav #else 8583d2307dSDag-Erling Smørgrav strlcpy(ret->d_name, od->dir[od->offset++]->filename, 8683d2307dSDag-Erling Smørgrav sizeof(ret->d_name)); 8783d2307dSDag-Erling Smørgrav #endif 8883d2307dSDag-Erling Smørgrav #ifdef __GNU_LIBRARY__ 8983d2307dSDag-Erling Smørgrav /* 9083d2307dSDag-Erling Smørgrav * Idiot glibc uses extensions to struct dirent for readdir with 9183d2307dSDag-Erling Smørgrav * ALTDIRFUNCs. Not that this is documented anywhere but the 9283d2307dSDag-Erling Smørgrav * source... Fake an inode number to appease it. 9383d2307dSDag-Erling Smørgrav */ 9483d2307dSDag-Erling Smørgrav ret->d_ino = inum++; 9583d2307dSDag-Erling Smørgrav if (!inum) 9683d2307dSDag-Erling Smørgrav inum = 1; 9783d2307dSDag-Erling Smørgrav #endif /* __GNU_LIBRARY__ */ 9883d2307dSDag-Erling Smørgrav 9983d2307dSDag-Erling Smørgrav return(ret); 1001e8db6e2SBrian Feldman } 1011e8db6e2SBrian Feldman 102ae1f160dSDag-Erling Smørgrav static void 103ae1f160dSDag-Erling Smørgrav fudge_closedir(struct SFTP_OPENDIR *od) 1041e8db6e2SBrian Feldman { 1051e8db6e2SBrian Feldman free_sftp_dirents(od->dir); 1061e8db6e2SBrian Feldman xfree(od); 1071e8db6e2SBrian Feldman } 1081e8db6e2SBrian Feldman 109ae1f160dSDag-Erling Smørgrav static int 110ae1f160dSDag-Erling Smørgrav fudge_lstat(const char *path, struct stat *st) 1111e8db6e2SBrian Feldman { 1121e8db6e2SBrian Feldman Attrib *a; 1131e8db6e2SBrian Feldman 114ae1f160dSDag-Erling Smørgrav if (!(a = do_lstat(cur.conn, (char *)path, 0))) 1151e8db6e2SBrian Feldman return(-1); 1161e8db6e2SBrian Feldman 1171e8db6e2SBrian Feldman attrib_to_stat(a, st); 1181e8db6e2SBrian Feldman 1191e8db6e2SBrian Feldman return(0); 1201e8db6e2SBrian Feldman } 1211e8db6e2SBrian Feldman 122ae1f160dSDag-Erling Smørgrav static int 123ae1f160dSDag-Erling Smørgrav fudge_stat(const char *path, struct stat *st) 1241e8db6e2SBrian Feldman { 1251e8db6e2SBrian Feldman Attrib *a; 1261e8db6e2SBrian Feldman 127ae1f160dSDag-Erling Smørgrav if (!(a = do_stat(cur.conn, (char *)path, 0))) 1281e8db6e2SBrian Feldman return(-1); 1291e8db6e2SBrian Feldman 1301e8db6e2SBrian Feldman attrib_to_stat(a, st); 1311e8db6e2SBrian Feldman 1321e8db6e2SBrian Feldman return(0); 1331e8db6e2SBrian Feldman } 1341e8db6e2SBrian Feldman 1351e8db6e2SBrian Feldman int 136ae1f160dSDag-Erling Smørgrav remote_glob(struct sftp_conn *conn, const char *pattern, int flags, 1371e8db6e2SBrian Feldman int (*errfunc)(const char *, int), glob_t *pglob) 1381e8db6e2SBrian Feldman { 139ae1f160dSDag-Erling Smørgrav pglob->gl_opendir = fudge_opendir; 140ae1f160dSDag-Erling Smørgrav pglob->gl_readdir = (struct dirent *(*)(void *))fudge_readdir; 141ae1f160dSDag-Erling Smørgrav pglob->gl_closedir = (void (*)(void *))fudge_closedir; 1421e8db6e2SBrian Feldman pglob->gl_lstat = fudge_lstat; 1431e8db6e2SBrian Feldman pglob->gl_stat = fudge_stat; 1441e8db6e2SBrian Feldman 1451e8db6e2SBrian Feldman memset(&cur, 0, sizeof(cur)); 146ae1f160dSDag-Erling Smørgrav cur.conn = conn; 1471e8db6e2SBrian Feldman 148ae1f160dSDag-Erling Smørgrav return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob)); 1491e8db6e2SBrian Feldman } 150