1 /* $NetBSD: sftp-glob.c,v 1.3 2010/07/06 15:09:41 christos Exp $ */ 2 /* $OpenBSD: sftp-glob.c,v 1.22 2006/08/03 03:34:42 deraadt Exp $ */ 3 /* 4 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "includes.h" 20 __RCSID("$NetBSD: sftp-glob.c,v 1.3 2010/07/06 15:09:41 christos Exp $"); 21 #include <sys/types.h> 22 #include <sys/stat.h> 23 24 #include <dirent.h> 25 #include <glob.h> 26 #include <string.h> 27 28 #include "xmalloc.h" 29 #include "sftp.h" 30 #include "buffer.h" 31 #include "sftp-common.h" 32 #include "sftp-client.h" 33 34 int remote_glob(struct sftp_conn *, const char *, int, 35 int (*)(const char *, int), glob_t *); 36 37 struct SFTP_OPENDIR { 38 SFTP_DIRENT **dir; 39 int offset; 40 }; 41 42 static struct { 43 struct sftp_conn *conn; 44 } cur; 45 46 static void * 47 fudge_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 63 static struct dirent * 64 fudge_readdir(struct SFTP_OPENDIR *od) 65 { 66 static struct dirent ret; 67 68 if (od->dir[od->offset] == NULL) 69 return(NULL); 70 71 memset(&ret, 0, sizeof(ret)); 72 strlcpy(ret.d_name, od->dir[od->offset++]->filename, 73 sizeof(ret.d_name)); 74 75 return(&ret); 76 } 77 78 static void 79 fudge_closedir(struct SFTP_OPENDIR *od) 80 { 81 free_sftp_dirents(od->dir); 82 xfree(od); 83 } 84 85 static int 86 fudge_lstat(const char *path, struct stat *st) 87 { 88 Attrib *a; 89 90 if (!(a = do_lstat(cur.conn, (char *)path, 0))) 91 return(-1); 92 93 attrib_to_stat(a, st); 94 95 return(0); 96 } 97 98 static int 99 fudge_stat(const char *path, struct stat *st) 100 { 101 Attrib *a; 102 103 if (!(a = do_stat(cur.conn, (char *)path, 0))) 104 return(-1); 105 106 attrib_to_stat(a, st); 107 108 return(0); 109 } 110 111 int 112 remote_glob(struct sftp_conn *conn, const char *pattern, int flags, 113 int (*errfunc)(const char *, int), glob_t *pglob) 114 { 115 pglob->gl_opendir = fudge_opendir; 116 pglob->gl_readdir = (struct dirent *(*)(void *))fudge_readdir; 117 pglob->gl_closedir = (void (*)(void *))fudge_closedir; 118 pglob->gl_lstat = fudge_lstat; 119 pglob->gl_stat = fudge_stat; 120 121 memset(&cur, 0, sizeof(cur)); 122 cur.conn = conn; 123 124 return(glob(pattern, flags|GLOB_ALTDIRFUNC|GLOB_LIMIT, errfunc, pglob)); 125 } 126