xref: /netbsd-src/crypto/external/bsd/openssh/dist/sftp-glob.c (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
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