blob: 16c5e206aa010c15e5e5bdc8298efb6970328b50 [file] [log] [blame]
Damien Miller4870afd2001-03-14 10:27:09 +11001/*
Damien Miller4e60ed72004-02-17 17:07:59 +11002 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
Damien Miller4870afd2001-03-14 10:27:09 +11003 *
Damien Miller4e60ed72004-02-17 17:07:59 +11004 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
Damien Miller4870afd2001-03-14 10:27:09 +11007 *
Damien Miller4e60ed72004-02-17 17:07:59 +11008 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Damien Miller4870afd2001-03-14 10:27:09 +110015 */
16
17#include "includes.h"
Damien Millerd7d46bb2004-02-18 14:11:13 +110018RCSID("$OpenBSD: sftp-glob.c,v 1.15 2004/02/17 07:17:29 djm Exp $");
Damien Miller4870afd2001-03-14 10:27:09 +110019
Damien Miller4870afd2001-03-14 10:27:09 +110020#include "buffer.h"
21#include "bufaux.h"
Damien Miller4870afd2001-03-14 10:27:09 +110022#include "xmalloc.h"
23#include "log.h"
Damien Miller4870afd2001-03-14 10:27:09 +110024
25#include "sftp.h"
26#include "sftp-common.h"
27#include "sftp-client.h"
Damien Millerd7d46bb2004-02-18 14:11:13 +110028
29int remote_glob(struct sftp_conn *, const char *, int,
30 int (*)(const char *, int), glob_t *);
Damien Miller4870afd2001-03-14 10:27:09 +110031
32struct SFTP_OPENDIR {
33 SFTP_DIRENT **dir;
34 int offset;
35};
36
37static struct {
Damien Miller3db5f532002-02-13 14:10:32 +110038 struct sftp_conn *conn;
Damien Miller4870afd2001-03-14 10:27:09 +110039} cur;
40
Ben Lindstrombba81212001-06-25 05:01:22 +000041static void *
42fudge_opendir(const char *path)
Damien Miller4870afd2001-03-14 10:27:09 +110043{
44 struct SFTP_OPENDIR *r;
Damien Miller9f0f5c62001-12-21 14:45:46 +110045
Damien Miller4870afd2001-03-14 10:27:09 +110046 r = xmalloc(sizeof(*r));
Damien Miller9f0f5c62001-12-21 14:45:46 +110047
Ben Lindstromc51b9242002-07-07 22:10:15 +000048 if (do_readdir(cur.conn, (char *)path, &r->dir)) {
49 xfree(r);
Damien Miller4870afd2001-03-14 10:27:09 +110050 return(NULL);
Ben Lindstromc51b9242002-07-07 22:10:15 +000051 }
Damien Miller4870afd2001-03-14 10:27:09 +110052
53 r->offset = 0;
54
Ben Lindstroma962c2f2002-07-04 00:14:17 +000055 return((void *)r);
Damien Miller4870afd2001-03-14 10:27:09 +110056}
57
Ben Lindstrombba81212001-06-25 05:01:22 +000058static struct dirent *
59fudge_readdir(struct SFTP_OPENDIR *od)
Damien Miller4870afd2001-03-14 10:27:09 +110060{
Damien Miller18bb4732001-03-28 14:35:30 +100061 /* Solaris needs sizeof(dirent) + path length (see below) */
62 static char buf[sizeof(struct dirent) + MAXPATHLEN];
63 struct dirent *ret = (struct dirent *)buf;
Damien Miller4870afd2001-03-14 10:27:09 +110064#ifdef __GNU_LIBRARY__
65 static int inum = 1;
66#endif /* __GNU_LIBRARY__ */
Damien Miller787b2ec2003-11-21 23:56:47 +110067
Damien Miller4870afd2001-03-14 10:27:09 +110068 if (od->dir[od->offset] == NULL)
69 return(NULL);
70
Damien Miller18bb4732001-03-28 14:35:30 +100071 memset(buf, 0, sizeof(buf));
Damien Miller4870afd2001-03-14 10:27:09 +110072
Damien Miller18bb4732001-03-28 14:35:30 +100073 /*
74 * Solaris defines dirent->d_name as a one byte array and expects
75 * you to hack around it.
76 */
77#ifdef BROKEN_ONE_BYTE_DIRENT_D_NAME
78 strlcpy(ret->d_name, od->dir[od->offset++]->filename, MAXPATHLEN);
79#else
Ben Lindstroma3700052001-04-05 23:26:32 +000080 strlcpy(ret->d_name, od->dir[od->offset++]->filename,
Damien Miller18bb4732001-03-28 14:35:30 +100081 sizeof(ret->d_name));
82#endif
Damien Miller4870afd2001-03-14 10:27:09 +110083#ifdef __GNU_LIBRARY__
84 /*
85 * Idiot glibc uses extensions to struct dirent for readdir with
Damien Millera8e06ce2003-11-21 23:48:55 +110086 * ALTDIRFUNCs. Not that this is documented anywhere but the
Damien Miller4870afd2001-03-14 10:27:09 +110087 * source... Fake an inode number to appease it.
88 */
Damien Miller18bb4732001-03-28 14:35:30 +100089 ret->d_ino = inum++;
Damien Miller4870afd2001-03-14 10:27:09 +110090 if (!inum)
91 inum = 1;
92#endif /* __GNU_LIBRARY__ */
93
Damien Miller18bb4732001-03-28 14:35:30 +100094 return(ret);
Damien Miller4870afd2001-03-14 10:27:09 +110095}
96
Ben Lindstrombba81212001-06-25 05:01:22 +000097static void
98fudge_closedir(struct SFTP_OPENDIR *od)
Damien Miller4870afd2001-03-14 10:27:09 +110099{
100 free_sftp_dirents(od->dir);
Ben Lindstrom86ebcb62001-04-04 01:53:20 +0000101 xfree(od);
Damien Miller4870afd2001-03-14 10:27:09 +1100102}
103
Ben Lindstrombba81212001-06-25 05:01:22 +0000104static int
105fudge_lstat(const char *path, struct stat *st)
Damien Miller4870afd2001-03-14 10:27:09 +1100106{
107 Attrib *a;
Damien Miller9f0f5c62001-12-21 14:45:46 +1100108
Ben Lindstroma962c2f2002-07-04 00:14:17 +0000109 if (!(a = do_lstat(cur.conn, (char *)path, 0)))
Damien Miller4870afd2001-03-14 10:27:09 +1100110 return(-1);
Damien Miller9f0f5c62001-12-21 14:45:46 +1100111
Damien Miller4870afd2001-03-14 10:27:09 +1100112 attrib_to_stat(a, st);
Damien Miller9f0f5c62001-12-21 14:45:46 +1100113
Damien Miller4870afd2001-03-14 10:27:09 +1100114 return(0);
115}
116
Ben Lindstrombba81212001-06-25 05:01:22 +0000117static int
118fudge_stat(const char *path, struct stat *st)
Damien Miller4870afd2001-03-14 10:27:09 +1100119{
120 Attrib *a;
Damien Miller9f0f5c62001-12-21 14:45:46 +1100121
Ben Lindstroma962c2f2002-07-04 00:14:17 +0000122 if (!(a = do_stat(cur.conn, (char *)path, 0)))
Damien Miller4870afd2001-03-14 10:27:09 +1100123 return(-1);
Damien Miller9f0f5c62001-12-21 14:45:46 +1100124
Damien Miller4870afd2001-03-14 10:27:09 +1100125 attrib_to_stat(a, st);
Damien Miller9f0f5c62001-12-21 14:45:46 +1100126
Damien Miller4870afd2001-03-14 10:27:09 +1100127 return(0);
128}
129
130int
Damien Miller3db5f532002-02-13 14:10:32 +1100131remote_glob(struct sftp_conn *conn, const char *pattern, int flags,
Ben Lindstrom206941f2001-04-15 14:27:16 +0000132 int (*errfunc)(const char *, int), glob_t *pglob)
Damien Miller4870afd2001-03-14 10:27:09 +1100133{
Damien Millerea12acf2001-07-14 12:14:56 +1000134 pglob->gl_opendir = fudge_opendir;
135 pglob->gl_readdir = (struct dirent *(*)(void *))fudge_readdir;
136 pglob->gl_closedir = (void (*)(void *))fudge_closedir;
Damien Miller4870afd2001-03-14 10:27:09 +1100137 pglob->gl_lstat = fudge_lstat;
138 pglob->gl_stat = fudge_stat;
Damien Miller9f0f5c62001-12-21 14:45:46 +1100139
Damien Miller4870afd2001-03-14 10:27:09 +1100140 memset(&cur, 0, sizeof(cur));
Damien Miller3db5f532002-02-13 14:10:32 +1100141 cur.conn = conn;
Damien Miller4870afd2001-03-14 10:27:09 +1100142
Damien Miller3db5f532002-02-13 14:10:32 +1100143 return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob));
Damien Miller4870afd2001-03-14 10:27:09 +1100144}