~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

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