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