~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/ntvfs/cifs_posix_cli/svfs_util.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   Unix SMB/CIFS implementation.
 
3
 
 
4
   simpler Samba VFS filesystem backend for clients which support the
 
5
   CIFS Unix Extensions or newer CIFS POSIX protocol extensions
 
6
 
 
7
 
 
8
   Copyright (C) Andrew Tridgell 2003
 
9
   Copyright (C) Steve French 2006
 
10
 
 
11
   This program is free software; you can redistribute it and/or modify
 
12
   it under the terms of the GNU General Public License as published by
 
13
   the Free Software Foundation; either version 3 of the License, or
 
14
   (at your option) any later version.
 
15
   
 
16
   This program is distributed in the hope that it will be useful,
 
17
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
   GNU General Public License for more details.
 
20
   
 
21
   You should have received a copy of the GNU General Public License
 
22
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
23
*/
 
24
/*
 
25
  utility functions for cifs posix backend
 
26
*/
 
27
 
 
28
#include "includes.h"
 
29
#include "system/filesys.h"
 
30
#include "cifsposix.h"
 
31
#include "system/time.h"
 
32
#include "system/dir.h"
 
33
#include "ntvfs/ntvfs.h"
 
34
#include "ntvfs/cifs_posix_cli/proto.h"
 
35
 
 
36
/*
 
37
  convert a windows path to a unix path - don't do any manging or case sensitive handling
 
38
*/
 
39
char *cifspsx_unix_path(struct ntvfs_module_context *ntvfs,
 
40
                     struct ntvfs_request *req, const char *name)
 
41
{
 
42
        struct cifspsx_private *p = ntvfs->private_data;
 
43
        char *ret;
 
44
 
 
45
        if (*name != '\\') {
 
46
                ret = talloc_asprintf(req, "%s/%s", p->connectpath, name);
 
47
        } else {
 
48
                ret = talloc_asprintf(req, "%s%s", p->connectpath, name);
 
49
        }
 
50
        all_string_sub(ret, "\\", "/", 0);
 
51
 
 
52
        strlower(ret + strlen(p->connectpath));
 
53
 
 
54
        return ret;
 
55
}
 
56
 
 
57
 
 
58
/*
 
59
  read a directory and find all matching file names and stat info
 
60
  returned names are separate unix and DOS names. The returned names
 
61
  are relative to the directory
 
62
*/
 
63
struct cifspsx_dir *cifspsx_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request *req, const char *unix_path)
 
64
{
 
65
        char *p, *mask;
 
66
        struct cifspsx_dir *dir;
 
67
        DIR *odir;
 
68
        struct dirent *dent;
 
69
        uint_t allocated = 0;
 
70
        char *low_mask;
 
71
 
 
72
        dir = talloc(mem_ctx, struct cifspsx_dir);
 
73
        if (!dir) { return NULL; }
 
74
 
 
75
        dir->count = 0;
 
76
        dir->files = 0;
 
77
 
 
78
        /* find the base directory */
 
79
        p = strrchr(unix_path, '/');
 
80
        if (!p) { return NULL; }
 
81
 
 
82
        dir->unix_dir = talloc_strndup(mem_ctx, unix_path, PTR_DIFF(p, unix_path));
 
83
        if (!dir->unix_dir) { return NULL; }
 
84
 
 
85
        /* the wildcard pattern is the last part */
 
86
        mask = p+1;
 
87
 
 
88
        low_mask = talloc_strdup(mem_ctx, mask);
 
89
        if (!low_mask) { return NULL; }
 
90
        strlower(low_mask);
 
91
 
 
92
        odir = opendir(dir->unix_dir);
 
93
        if (!odir) { return NULL; }
 
94
 
 
95
        while ((dent = readdir(odir))) {
 
96
                uint_t i = dir->count;
 
97
                char *full_name;
 
98
                char *low_name;
 
99
 
 
100
                if (strchr(dent->d_name, ':') && !strchr(unix_path, ':')) {
 
101
                        /* don't show streams in dir listing */
 
102
                        continue;
 
103
                }
 
104
 
 
105
                low_name = talloc_strdup(mem_ctx, dent->d_name);
 
106
                if (!low_name) { continue; }
 
107
                strlower(low_name);
 
108
 
 
109
                /* check it matches the wildcard pattern */
 
110
                if (ms_fnmatch(low_mask, low_name, PROTOCOL_NT1) != 0) {
 
111
                        continue;
 
112
                }
 
113
                
 
114
                if (dir->count >= allocated) {
 
115
                        allocated = (allocated + 100) * 1.2;
 
116
                        dir->files = talloc_realloc(dir, dir->files, struct cifspsx_dirfile, allocated);
 
117
                        if (!dir->files) { 
 
118
                                closedir(odir);
 
119
                                return NULL;
 
120
                        }
 
121
                }
 
122
 
 
123
                dir->files[i].name = low_name;
 
124
                if (!dir->files[i].name) { continue; }
 
125
 
 
126
                asprintf(&full_name, "%s/%s", dir->unix_dir, dir->files[i].name);
 
127
                if (!full_name) { continue; }
 
128
 
 
129
                if (stat(full_name, &dir->files[i].st) == 0) { 
 
130
                        dir->count++;
 
131
                }
 
132
 
 
133
                free(full_name); 
 
134
        }
 
135
 
 
136
        closedir(odir);
 
137
 
 
138
        return dir;
 
139
}
 
140
 
 
141
/*
 
142
  read a directory and find all matching file names and stat info
 
143
  returned names are separate unix and DOS names. The returned names
 
144
  are relative to the directory
 
145
*/
 
146
struct cifspsx_dir *cifspsx_list(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const char *pattern)
 
147
{
 
148
        struct cifspsx_private *p = ntvfs->private_data;
 
149
        char *unix_path;
 
150
 
 
151
        unix_path = cifspsx_unix_path(ntvfs, req, pattern);
 
152
        if (!unix_path) { return NULL; }
 
153
 
 
154
        return cifspsx_list_unix(p, req, unix_path);
 
155
}
 
156
 
 
157
 
 
158
/*******************************************************************
 
159
set the time on a file via file descriptor
 
160
*******************************************************************/
 
161
int cifspsx_file_utime(int fd, struct utimbuf *times)
 
162
{
 
163
        char *fd_path = NULL;
 
164
        int ret;
 
165
 
 
166
        asprintf(&fd_path, "/proc/self/%d", fd);
 
167
        if (!fd_path) {
 
168
                errno = ENOMEM;
 
169
                return -1;
 
170
        }
 
171
        
 
172
        ret = utime(fd_path, times);
 
173
        free(fd_path);
 
174
        return ret;
 
175
}
 
176
 
 
177
 
 
178
/*
 
179
  map a unix file attrib to a DOS attribute
 
180
*/
 
181
uint16_t cifspsx_unix_to_dos_attrib(mode_t mode)
 
182
{
 
183
        uint16_t ret = 0;
 
184
        if (S_ISDIR(mode)) ret |= FILE_ATTRIBUTE_DIRECTORY;
 
185
        if (!(mode & S_IWUSR)) ret |= FILE_ATTRIBUTE_READONLY;
 
186
        return ret;
 
187
}
 
188