1 /* $OpenBSD: sftp-glob.c,v 1.22 2006/08/03 03:34:42 deraadt Exp $ */ 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 <sys/types.h> 19 #include <sys/stat.h> 20 21 #include <dirent.h> 22 #include <glob.h> 23 #include <string.h> 24 25 #include "xmalloc.h" 26 #include "sftp.h" 27 #include "buffer.h" 28 #include "sftp-common.h" 29 #include "sftp-client.h" 30 31 int remote_glob(struct sftp_conn *, const char *, int, 32 int (*)(const char *, int), glob_t *); 33 34 struct SFTP_OPENDIR { 35 SFTP_DIRENT **dir; 36 int offset; 37 }; 38 39 static struct { 40 struct sftp_conn *conn; 41 } cur; 42 43 static void * 44 fudge_opendir(const char *path) 45 { 46 struct SFTP_OPENDIR *r; 47 48 r = xmalloc(sizeof(*r)); 49 50 if (do_readdir(cur.conn, (char *)path, &r->dir)) { 51 xfree(r); 52 return(NULL); 53 } 54 55 r->offset = 0; 56 57 return((void *)r); 58 } 59 60 static struct dirent * 61 fudge_readdir(struct SFTP_OPENDIR *od) 62 { 63 static struct dirent ret; 64 65 if (od->dir[od->offset] == NULL) 66 return(NULL); 67 68 memset(&ret, 0, sizeof(ret)); 69 strlcpy(ret.d_name, od->dir[od->offset++]->filename, 70 sizeof(ret.d_name)); 71 72 return(&ret); 73 } 74 75 static void 76 fudge_closedir(struct SFTP_OPENDIR *od) 77 { 78 free_sftp_dirents(od->dir); 79 xfree(od); 80 } 81 82 static int 83 fudge_lstat(const char *path, struct stat *st) 84 { 85 Attrib *a; 86 87 if (!(a = do_lstat(cur.conn, (char *)path, 0))) 88 return(-1); 89 90 attrib_to_stat(a, st); 91 92 return(0); 93 } 94 95 static int 96 fudge_stat(const char *path, struct stat *st) 97 { 98 Attrib *a; 99 100 if (!(a = do_stat(cur.conn, (char *)path, 0))) 101 return(-1); 102 103 attrib_to_stat(a, st); 104 105 return(0); 106 } 107 108 int 109 remote_glob(struct sftp_conn *conn, const char *pattern, int flags, 110 int (*errfunc)(const char *, int), glob_t *pglob) 111 { 112 pglob->gl_opendir = fudge_opendir; 113 pglob->gl_readdir = (struct dirent *(*)(void *))fudge_readdir; 114 pglob->gl_closedir = (void (*)(void *))fudge_closedir; 115 pglob->gl_lstat = fudge_lstat; 116 pglob->gl_stat = fudge_stat; 117 118 memset(&cur, 0, sizeof(cur)); 119 cur.conn = conn; 120 121 return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob)); 122 } 123