11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: sftp-glob.c,v 1.22 2006/08/03 03:34:42 deraadt Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Permission to use, copy, modify, and distribute this software for any 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * purpose with or without fee is hereby granted, provided that the above 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * copyright notice and this permission notice appear in all copies. 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SYS_STAT_H 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <sys/stat.h> 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <dirent.h> 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h" 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "sftp.h" 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h" 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "sftp-common.h" 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "sftp-client.h" 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint remote_glob(struct sftp_conn *, const char *, int, 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int (*)(const char *, int), glob_t *); 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct SFTP_OPENDIR { 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SFTP_DIRENT **dir; 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int offset; 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}; 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic struct { 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct sftp_conn *conn; 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} cur; 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void * 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodfudge_opendir(const char *path) 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct SFTP_OPENDIR *r; 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood r = xmalloc(sizeof(*r)); 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (do_readdir(cur.conn, (char *)path, &r->dir)) { 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(r); 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return(NULL); 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood r->offset = 0; 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return((void *)r); 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic struct dirent * 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodfudge_readdir(struct SFTP_OPENDIR *od) 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Solaris needs sizeof(dirent) + path length (see below) */ 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static char buf[sizeof(struct dirent) + MAXPATHLEN]; 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct dirent *ret = (struct dirent *)buf; 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef __GNU_LIBRARY__ 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static int inum = 1; 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* __GNU_LIBRARY__ */ 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (od->dir[od->offset] == NULL) 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return(NULL); 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(buf, 0, sizeof(buf)); 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Solaris defines dirent->d_name as a one byte array and expects 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * you to hack around it. 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef BROKEN_ONE_BYTE_DIRENT_D_NAME 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcpy(ret->d_name, od->dir[od->offset++]->filename, MAXPATHLEN); 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcpy(ret->d_name, od->dir[od->offset++]->filename, 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sizeof(ret->d_name)); 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef __GNU_LIBRARY__ 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Idiot glibc uses extensions to struct dirent for readdir with 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ALTDIRFUNCs. Not that this is documented anywhere but the 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * source... Fake an inode number to appease it. 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret->d_ino = inum++; 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!inum) 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood inum = 1; 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* __GNU_LIBRARY__ */ 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return(ret); 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodfudge_closedir(struct SFTP_OPENDIR *od) 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free_sftp_dirents(od->dir); 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(od); 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodfudge_lstat(const char *path, struct stat *st) 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Attrib *a; 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!(a = do_lstat(cur.conn, (char *)path, 0))) 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return(-1); 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood attrib_to_stat(a, st); 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return(0); 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodfudge_stat(const char *path, struct stat *st) 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Attrib *a; 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!(a = do_stat(cur.conn, (char *)path, 0))) 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return(-1); 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood attrib_to_stat(a, st); 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return(0); 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodremote_glob(struct sftp_conn *conn, const char *pattern, int flags, 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int (*errfunc)(const char *, int), glob_t *pglob) 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pglob->gl_opendir = fudge_opendir; 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pglob->gl_readdir = (struct dirent *(*)(void *))fudge_readdir; 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pglob->gl_closedir = (void (*)(void *))fudge_closedir; 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pglob->gl_lstat = fudge_lstat; 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pglob->gl_stat = fudge_stat; 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(&cur, 0, sizeof(cur)); 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cur.conn = conn; 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob)); 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 150