2/* 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18#include "includes.h"
|
31#include "sftp-common.h" 32#include "sftp-client.h" 33 34int remote_glob(struct sftp_conn *, const char *, int, 35 int (*)(const char *, int), glob_t *); 36 37struct SFTP_OPENDIR { 38 SFTP_DIRENT **dir; 39 int offset; 40}; 41 42static struct { 43 struct sftp_conn *conn; 44} cur; 45 46static void * 47fudge_opendir(const char *path) 48{ 49 struct SFTP_OPENDIR *r; 50 51 r = xmalloc(sizeof(*r)); 52 53 if (do_readdir(cur.conn, (char *)path, &r->dir)) { 54 xfree(r); 55 return(NULL); 56 } 57 58 r->offset = 0; 59 60 return((void *)r); 61} 62 63static struct dirent * 64fudge_readdir(struct SFTP_OPENDIR *od) 65{ 66 /* Solaris needs sizeof(dirent) + path length (see below) */ 67 static char buf[sizeof(struct dirent) + MAXPATHLEN]; 68 struct dirent *ret = (struct dirent *)buf; 69#ifdef __GNU_LIBRARY__ 70 static int inum = 1; 71#endif /* __GNU_LIBRARY__ */ 72 73 if (od->dir[od->offset] == NULL) 74 return(NULL); 75 76 memset(buf, 0, sizeof(buf)); 77 78 /* 79 * Solaris defines dirent->d_name as a one byte array and expects 80 * you to hack around it. 81 */ 82#ifdef BROKEN_ONE_BYTE_DIRENT_D_NAME 83 strlcpy(ret->d_name, od->dir[od->offset++]->filename, MAXPATHLEN); 84#else 85 strlcpy(ret->d_name, od->dir[od->offset++]->filename, 86 sizeof(ret->d_name)); 87#endif 88#ifdef __GNU_LIBRARY__ 89 /* 90 * Idiot glibc uses extensions to struct dirent for readdir with 91 * ALTDIRFUNCs. Not that this is documented anywhere but the 92 * source... Fake an inode number to appease it. 93 */ 94 ret->d_ino = inum++; 95 if (!inum) 96 inum = 1; 97#endif /* __GNU_LIBRARY__ */ 98 99 return(ret); 100} 101 102static void 103fudge_closedir(struct SFTP_OPENDIR *od) 104{ 105 free_sftp_dirents(od->dir); 106 xfree(od); 107} 108 109static int 110fudge_lstat(const char *path, struct stat *st) 111{ 112 Attrib *a; 113 114 if (!(a = do_lstat(cur.conn, (char *)path, 0))) 115 return(-1); 116 117 attrib_to_stat(a, st); 118 119 return(0); 120} 121 122static int 123fudge_stat(const char *path, struct stat *st) 124{ 125 Attrib *a; 126 127 if (!(a = do_stat(cur.conn, (char *)path, 0))) 128 return(-1); 129 130 attrib_to_stat(a, st); 131 132 return(0); 133} 134 135int 136remote_glob(struct sftp_conn *conn, const char *pattern, int flags, 137 int (*errfunc)(const char *, int), glob_t *pglob) 138{ 139 pglob->gl_opendir = fudge_opendir; 140 pglob->gl_readdir = (struct dirent *(*)(void *))fudge_readdir; 141 pglob->gl_closedir = (void (*)(void *))fudge_closedir; 142 pglob->gl_lstat = fudge_lstat; 143 pglob->gl_stat = fudge_stat; 144 145 memset(&cur, 0, sizeof(cur)); 146 cur.conn = conn; 147 148 return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob)); 149}
|