A new utility to test VFS system and modules
[mimir/samba.git] / source3 / torture / cmd_vfs.c
1 /* 
2    Unix SMB/CIFS implementation.
3    VFS module functions
4
5    Copyright (C) Simo Sorce 2002
6    Copyright (C) Eric Lorimer 2002
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 2 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, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "vfstest.h"
25
26 static char *null_string = "";
27
28 static NTSTATUS cmd_load_module(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
29 {
30         struct smb_vfs_handle_struct *handle;
31         
32         if (argc != 2) {
33                 printf("Usage: load <module path>\n");
34                 return NT_STATUS_OK;
35         }
36         vfs->conn->vfs_private = NULL;
37         handle = (struct smb_vfs_handle_struct *) smb_xmalloc(sizeof(smb_vfs_handle_struct));
38         handle->handle = NULL;
39         DLIST_ADD(vfs->conn->vfs_private, handle)
40         if (!vfs_init_custom(vfs->conn, argv[1])) {
41                 DEBUG(0, ("load: error=-1 (vfs_init_custom failed for %s)\n", argv[1]));
42                 return NT_STATUS_UNSUCCESSFUL;
43         }
44         printf("load: ok\n");
45         return NT_STATUS_OK;
46 }
47
48 static NTSTATUS cmd_populate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
49 {
50         char c;
51         size_t size;
52         if (argc != 3) {
53                 printf("Usage: populate <char> <size>\n");
54                 return NT_STATUS_OK;
55         }
56         c = argv[1][0];
57         size = atoi(argv[2]);
58         vfs->data = (char *)talloc(mem_ctx, size);
59         if (vfs->data == NULL) {
60                 printf("read: error=-1 (not enough memory)");
61                 return NT_STATUS_UNSUCCESSFUL;
62         }
63         memset(vfs->data, c, size);
64         vfs->data_size = size;
65         return NT_STATUS_OK;
66 }
67
68 static NTSTATUS cmd_show_data(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
69 {
70         size_t offset;
71         size_t len;
72         if (argc != 1 && argc != 3) {
73                 printf("Usage: showdata [<offset> <len>]\n");
74                 return NT_STATUS_OK;
75         }
76         if (vfs->data == NULL || vfs->data_size == 0) {
77                 printf("show_data: error=-1 (buffer empty)\n");
78                 return NT_STATUS_UNSUCCESSFUL;
79         }
80
81         if (argc == 3) {
82                 offset = atoi(argv[1]);
83                 len = atoi(argv[2]);
84         } else {
85                 offset = 0;
86                 len = vfs->data_size;
87         }
88         if ((offset + len) > vfs->data_size) {
89                 printf("show_data: error=-1 (not enough data in buffer)\n");
90                 return NT_STATUS_UNSUCCESSFUL;
91         }
92         dump_data(0, (char *)(vfs->data) + offset, len);
93         return NT_STATUS_OK;
94 }
95
96 static NTSTATUS cmd_connect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
97 {
98         vfs->conn->vfs_ops.connect(vfs->conn, lp_servicename(vfs->conn->service), "vfstest");
99         return NT_STATUS_OK;
100 }
101
102 static NTSTATUS cmd_disconnect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
103 {
104         vfs->conn->vfs_ops.disconnect(vfs->conn);
105         return NT_STATUS_OK;
106 }
107
108 static NTSTATUS cmd_disk_free(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
109 {
110         SMB_BIG_UINT diskfree, bsize, dfree, dsize;
111         if (argc != 2) {
112                 printf("Usage: disk_free <path>\n");
113                 return NT_STATUS_OK;
114         }
115
116         diskfree = vfs->conn->vfs_ops.disk_free(vfs->conn, argv[1], False, &bsize, &dfree, &dsize);
117         printf("disk_free: %ld, bsize = %ld, dfree = %ld, dsize = %ld\n", diskfree, bsize, dfree, dsize);
118         return NT_STATUS_OK;
119 }
120
121
122 static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
123 {
124         if (argc != 2) {
125                 printf("Usage: opendir <fname>\n");
126                 return NT_STATUS_OK;
127         }
128
129         vfs->currentdir = vfs->conn->vfs_ops.opendir(vfs->conn, argv[1]);
130         if (vfs->currentdir == NULL) {
131                 printf("opendir error=%d (%s)\n", errno, strerror(errno));
132                 return NT_STATUS_UNSUCCESSFUL;
133         }
134
135         printf("opendir: ok\n");
136         return NT_STATUS_OK;
137 }
138
139
140 static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
141 {
142         struct dirent *dent;
143
144         if (vfs->currentdir == NULL) {
145                 printf("readdir: error=-1 (no open directory)\n");
146                 return NT_STATUS_UNSUCCESSFUL;
147         }
148
149         dent = vfs->conn->vfs_ops.readdir(vfs->conn, vfs->currentdir);
150         if (dent == NULL) {
151                 printf("readdir: NULL\n");
152                 return NT_STATUS_OK;
153         }
154
155         printf("readdir: %s\n", dent->d_name);
156         return NT_STATUS_OK;
157 }
158
159
160 static NTSTATUS cmd_mkdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
161 {
162         if (argc != 2) {
163                 printf("Usage: mkdir <path>\n");
164                 return NT_STATUS_OK;
165         }
166
167         if (vfs->conn->vfs_ops.mkdir(vfs->conn, argv[1], 00755) == -1) {
168                 printf("mkdir error=%d (%s)\n", errno, strerror(errno));
169                 return NT_STATUS_UNSUCCESSFUL;
170         }
171         
172         printf("mkdir: ok\n");
173         return NT_STATUS_OK;
174 }
175
176
177 static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
178 {
179         int ret;
180         
181         if (vfs->currentdir == NULL) {
182                 printf("closedir: failure (no directory open)\n");
183                 return NT_STATUS_UNSUCCESSFUL;
184         }
185
186         ret = vfs->conn->vfs_ops.closedir(vfs->conn, vfs->currentdir);
187         if (ret == -1) {
188                 printf("closedir failure: %s\n", strerror(errno));
189                 return NT_STATUS_UNSUCCESSFUL;
190         }
191
192         printf("closedir: ok\n");
193         vfs->currentdir = NULL;
194         return NT_STATUS_OK;
195 }
196
197
198 static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
199 {
200         int flags, mode, fd;
201
202         flags = O_RDWR | O_CREAT;
203         mode = 00400;
204
205         if (argc != 2) {
206                 printf("Usage: open <filename>\n");
207                 return NT_STATUS_OK;
208         }
209
210         fd = vfs->conn->vfs_ops.open(vfs->conn, argv[1], flags, mode);
211         if (fd == -1) {
212                 printf("open: error=%d (%s)\n", errno, strerror(errno));
213                 return NT_STATUS_UNSUCCESSFUL;
214         }
215
216         vfs->files[fd] = (struct files_struct *)malloc(sizeof(struct files_struct));
217         vfs->files[fd]->fsp_name = strdup(argv[1]);
218         vfs->files[fd]->fd = fd;
219         vfs->files[fd]->conn = vfs->conn;
220         printf("open: fd=%d\n", fd);
221         return NT_STATUS_OK;
222 }
223
224
225 static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
226 {
227         int ret = -1;
228         struct func_entry *fptr;
229         struct func_entry func_table[] = {
230                 { "rmdir",              vfs->conn->vfs_ops.rmdir },
231                 { "unlink",             vfs->conn->vfs_ops.unlink },
232                 { "chdir",              vfs->conn->vfs_ops.chdir },
233                 { NULL }
234         };
235
236         if (argc != 2) {
237                 printf("Usage: %s <path>\n", argv[0]);
238                 return NT_STATUS_OK;
239         }
240
241         for (fptr=func_table; *fptr->name; fptr++)
242                 if (strcmp(fptr->name, argv[0]) == 0 )
243                         ret = fptr->fn(vfs->conn, argv[1]);
244
245         if (ret == -1) {
246                 printf("%s: error=%d (%s)\n", argv[0], errno, strerror(errno));
247                 return NT_STATUS_UNSUCCESSFUL;
248         }
249
250         printf("%s: ok\n", argv[0]);
251         return NT_STATUS_OK;
252 }
253
254
255 static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
256 {
257         int fd, ret;
258
259         if (argc != 2) {
260                 printf("Usage: close <fd>\n");
261                 return NT_STATUS_OK;
262         }
263
264         fd = atoi(argv[1]);
265         if (vfs->files[fd] == NULL) {
266                 printf("close: error=-1 (invalid file descriptor)\n");
267                 return NT_STATUS_OK;
268         }
269
270         ret = vfs->conn->vfs_ops.close(vfs->files[fd], fd);
271         if (ret == -1 )
272                 printf("close: error=%d (%s)\n", errno, strerror(errno));
273         else
274                 printf("close: ok\n");
275
276         SAFE_FREE(vfs->files[fd]->fsp_name);
277         SAFE_FREE(vfs->files[fd]);
278         vfs->files[fd] = NULL;
279         return NT_STATUS_OK;
280 }
281
282
283 static NTSTATUS cmd_read(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
284 {
285         int fd;
286         size_t size, rsize;
287
288         if (argc != 3) {
289                 printf("Usage: read <fd> <size>\n");
290                 return NT_STATUS_OK;
291         }
292
293         /* do some error checking on these */
294         fd = atoi(argv[1]);
295         size = atoi(argv[2]);
296         vfs->data = (char *)talloc(mem_ctx, size);
297         if (vfs->data == NULL) {
298                 printf("read: error=-1 (not enough memory)");
299                 return NT_STATUS_UNSUCCESSFUL;
300         }
301         vfs->data_size = size;
302         
303         rsize = 0;
304         while (rsize < size) {
305                 int isize;
306                 isize = vfs->conn->vfs_ops.read(vfs->files[fd], fd, vfs->data, size);
307                 if (isize == -1) {
308                         printf("read: error=%d (%s)\n", errno, strerror(errno));
309                         return NT_STATUS_UNSUCCESSFUL;
310                 }
311                 rsize += isize;
312         }
313
314         printf("read: ok\n");
315         return NT_STATUS_OK;
316 }
317
318
319 static NTSTATUS cmd_write(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
320 {
321         int fd, size, wsize;
322
323         if (argc != 3) {
324                 printf("Usage: write <fd> <size>\n");
325                 return NT_STATUS_OK;
326         }
327
328         /* some error checking should go here */
329         fd = atoi(argv[1]);
330         size = atoi(argv[2]);
331         if (vfs->data == NULL) {
332                 printf("write: error=-1 (buffer empty, please populate it before writing)");
333                 return NT_STATUS_UNSUCCESSFUL;
334         }
335
336         if (vfs->data_size < size) {
337                 printf("write: error=-1 (buffer too small, please put some more data in)");
338                 return NT_STATUS_UNSUCCESSFUL;
339         }
340
341         wsize = vfs->conn->vfs_ops.write(vfs->files[fd], fd, vfs->data, size);
342
343         if (wsize == -1) {
344                 printf("write: error=%d (%s)\n", errno, strerror(errno));
345                 return NT_STATUS_UNSUCCESSFUL;
346         }
347
348         printf("write: ok\n");
349         return NT_STATUS_OK;
350 }
351
352
353 static NTSTATUS cmd_lseek(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
354 {
355         int fd, offset, whence;
356         SMB_OFF_T pos;
357
358         if (argc != 4) {
359                 printf("Usage: lseek <fd> <offset> <whence>\n...where whence is 1 => SEEK_SET, 2 => SEEK_CUR, 3 => SEEK_END\n");
360                 return NT_STATUS_OK;
361         }
362
363         fd = atoi(argv[1]);
364         offset = atoi(argv[2]);
365         whence = atoi(argv[3]);
366         switch (whence) {
367                 case 1:         whence = SEEK_SET; break;
368                 case 2:         whence = SEEK_CUR; break;
369                 default:        whence = SEEK_END;
370         }
371
372         pos = vfs->conn->vfs_ops.lseek(vfs->files[fd], fd, offset, whence);
373         if (pos == (SMB_OFF_T)-1) {
374                 printf("lseek: error=%d (%s)\n", errno, strerror(errno));
375                 return NT_STATUS_UNSUCCESSFUL;
376         }
377
378         printf("lseek: ok\n");
379         return NT_STATUS_OK;
380 }
381
382
383 static NTSTATUS cmd_rename(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
384 {
385         int ret;
386         if (argc != 3) {
387                 printf("Usage: rename <old> <new>\n");
388                 return NT_STATUS_OK;
389         }
390
391         ret = vfs->conn->vfs_ops.rename(vfs->conn, argv[1], argv[2]);
392         if (ret == -1) {
393                 printf("rename: error=%d (%s)\n", errno, strerror(errno));
394                 return NT_STATUS_UNSUCCESSFUL;
395         }
396
397         printf("rename: ok\n");
398         return NT_STATUS_OK;
399 }
400
401
402 static NTSTATUS cmd_fsync(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
403 {
404         int ret, fd;
405         if (argc != 2) {
406                 printf("Usage: fsync <fd>\n");
407                 return NT_STATUS_OK;
408         }
409
410         fd = atoi(argv[1]);
411         ret = vfs->conn->vfs_ops.fsync(vfs->files[fd], fd);
412         if (ret == -1) {
413                 printf("fsync: error=%d (%s)\n", errno, strerror(errno));
414                 return NT_STATUS_UNSUCCESSFUL;
415         }
416
417         printf("fsync: ok\n");
418         return NT_STATUS_OK;
419 }
420
421
422 static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
423 {
424         int ret;
425         char *user;
426         char *group;
427         struct passwd *pwd;
428         struct group *grp;
429         SMB_STRUCT_STAT st;
430
431         if (argc != 2) {
432                 printf("Usage: stat <fname>\n");
433                 return NT_STATUS_OK;
434         }
435
436         ret = vfs->conn->vfs_ops.stat(vfs->conn, argv[1], &st);
437         if (ret == -1) {
438                 printf("stat: error=%d (%s)\n", errno, strerror(errno));
439                 return NT_STATUS_UNSUCCESSFUL;
440         }
441
442         pwd = sys_getpwuid(st.st_uid);
443         if (pwd != NULL) user = strdup(pwd->pw_name);
444         else user = null_string;
445         grp = sys_getgrgid(st.st_gid);
446         if (grp != NULL) group = strdup(grp->gr_name);
447         else group = null_string;
448
449         printf("stat: ok\n");
450         printf("  File: %s", argv[1]);
451         if (S_ISREG(st.st_mode)) printf("  Regular File\n");
452         else if (S_ISDIR(st.st_mode)) printf("  Directory\n");
453         else if (S_ISCHR(st.st_mode)) printf("  Character Device\n");
454         else if (S_ISBLK(st.st_mode)) printf("  Block Device\n");
455         else if (S_ISFIFO(st.st_mode)) printf("  Fifo\n");
456         else if (S_ISLNK(st.st_mode)) printf("  Symbolic Link\n");
457         else if (S_ISSOCK(st.st_mode)) printf("  Socket\n");
458         printf("  Size: %10d", st.st_size);
459         printf(" Blocks: %9d", st.st_blocks);
460         printf(" IO Block: %d\n", st.st_blksize);
461         printf("  Device: 0x%.10x", st.st_dev);
462         printf(" Inode: %10d", st.st_ino);
463         printf(" Links: %10d\n", st.st_nlink);
464         printf("  Access: %05d     ", (st.st_mode) & 0x7fff);
465         printf(" Uid: %5d/%.16s Gid: %5d/%.16s\n", st.st_uid, user, st.st_gid, group);
466         printf("  Access: %s", ctime(&(st.st_atime)));
467         printf("  Modify: %s", ctime(&(st.st_mtime)));
468         printf("  Change: %s", ctime(&(st.st_ctime)));
469         if (user != null_string) SAFE_FREE(user);
470         if (group!= null_string) SAFE_FREE(group);
471         return NT_STATUS_OK;
472 }
473
474
475 static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
476 {
477         int fd;
478         char *user;
479         char *group;
480         struct passwd *pwd;
481         struct group *grp;
482         SMB_STRUCT_STAT st;
483
484         if (argc != 2) {
485                 printf("Usage: fstat <fd>\n");
486                 return NT_STATUS_OK;
487         }
488
489         fd = atoi(argv[1]);
490         if (fd < 0 || fd > 1024) {
491                 printf("fstat: error=%d (file descriptor out of range)\n", EBADF);
492                 return NT_STATUS_OK;
493         }
494
495         if (vfs->files[fd] == NULL) {
496                 printf("fstat: error=%d (invalid file descriptor)\n", EBADF);
497                 return NT_STATUS_OK;
498         }
499
500         if (vfs->conn->vfs_ops.fstat(vfs->files[fd], fd, &st) == -1) {
501                 printf("fstat: error=%d (%s)\n", errno, strerror(errno));
502                 return NT_STATUS_UNSUCCESSFUL;
503         }
504
505         pwd = sys_getpwuid(st.st_uid);
506         if (pwd != NULL) user = strdup(pwd->pw_name);
507         else user = null_string;
508         grp = sys_getgrgid(st.st_gid);
509         if (grp != NULL) group = strdup(grp->gr_name);
510         else group = null_string;
511
512         printf("fstat: ok\n");
513         if (S_ISREG(st.st_mode)) printf("  Regular File\n");
514         else if (S_ISDIR(st.st_mode)) printf("  Directory\n");
515         else if (S_ISCHR(st.st_mode)) printf("  Character Device\n");
516         else if (S_ISBLK(st.st_mode)) printf("  Block Device\n");
517         else if (S_ISFIFO(st.st_mode)) printf("  Fifo\n");
518         else if (S_ISLNK(st.st_mode)) printf("  Symbolic Link\n");
519         else if (S_ISSOCK(st.st_mode)) printf("  Socket\n");
520         printf("  Size: %10d", st.st_size);
521         printf(" Blocks: %9d", st.st_blocks);
522         printf(" IO Block: %d\n", st.st_blksize);
523         printf("  Device: 0x%10x", st.st_dev);
524         printf(" Inode: %10d", st.st_ino);
525         printf(" Links: %10d\n", st.st_nlink);
526         printf("  Access: %05d     ", (st.st_mode) & 0x7fff);
527         printf(" Uid: %5d/%.16s Gid: %5d/%.16s\n", st.st_uid, user, st.st_gid, group);
528         printf("  Access: %s", ctime(&(st.st_atime)));
529         printf("  Modify: %s", ctime(&(st.st_mtime)));
530         printf("  Change: %s", ctime(&(st.st_ctime)));
531         if (user != null_string) SAFE_FREE(user);
532         if (group!= null_string) SAFE_FREE(group);
533         return NT_STATUS_OK;
534 }
535
536
537 static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
538 {
539         char *user;
540         char *group;
541         struct passwd *pwd;
542         struct group *grp;
543         SMB_STRUCT_STAT st;
544
545         if (argc != 2) {
546                 printf("Usage: lstat <path>\n");
547                 return NT_STATUS_OK;
548         }
549
550         if (vfs->conn->vfs_ops.lstat(vfs->conn, argv[1], &st) == -1) {
551                 printf("lstat: error=%d (%s)\n", errno, strerror(errno));
552                 return NT_STATUS_UNSUCCESSFUL;
553         }
554
555         pwd = sys_getpwuid(st.st_uid);
556         if (pwd != NULL) user = strdup(pwd->pw_name);
557         else user = null_string;
558         grp = sys_getgrgid(st.st_gid);
559         if (grp != NULL) group = strdup(grp->gr_name);
560         else group = null_string;
561
562         printf("lstat: ok\n");
563         if (S_ISREG(st.st_mode)) printf("  Regular File\n");
564         else if (S_ISDIR(st.st_mode)) printf("  Directory\n");
565         else if (S_ISCHR(st.st_mode)) printf("  Character Device\n");
566         else if (S_ISBLK(st.st_mode)) printf("  Block Device\n");
567         else if (S_ISFIFO(st.st_mode)) printf("  Fifo\n");
568         else if (S_ISLNK(st.st_mode)) printf("  Symbolic Link\n");
569         else if (S_ISSOCK(st.st_mode)) printf("  Socket\n");
570         printf("  Size: %10d", st.st_size);
571         printf(" Blocks: %9d", st.st_blocks);
572         printf(" IO Block: %d\n", st.st_blksize);
573         printf("  Device: 0x%10x", st.st_dev);
574         printf(" Inode: %10d", st.st_ino);
575         printf(" Links: %10d\n", st.st_nlink);
576         printf("  Access: %05d     ", (st.st_mode) & 0x7fff);
577         printf(" Uid: %5d/%.16s Gid: %5d/%.16s\n", st.st_uid, user, st.st_gid, group);
578         printf("  Access: %s", ctime(&(st.st_atime)));
579         printf("  Modify: %s", ctime(&(st.st_mtime)));
580         printf("  Change: %s", ctime(&(st.st_ctime)));
581         if (user != null_string) SAFE_FREE(user);
582         if (group!= null_string) SAFE_FREE(group);
583         return NT_STATUS_OK;
584 }
585
586
587 static NTSTATUS cmd_chmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
588 {
589         mode_t mode;
590         if (argc != 3) {
591                 printf("Usage: chmod <path> <mode>\n");
592                 return NT_STATUS_OK;
593         }
594
595         mode = atoi(argv[2]);
596         if (vfs->conn->vfs_ops.chmod(vfs->conn, argv[1], mode) == -1) {
597                 printf("chmod: error=%d (%s)\n", errno, strerror(errno));
598                 return NT_STATUS_UNSUCCESSFUL;
599         }
600
601         printf("chmod: ok\n");
602         return NT_STATUS_OK;
603 }
604
605
606 static NTSTATUS cmd_fchmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
607 {
608         int fd;
609         mode_t mode;
610         if (argc != 3) {
611                 printf("Usage: fchmod <fd> <mode>\n");
612                 return NT_STATUS_OK;
613         }
614
615         fd = atoi(argv[1]);
616         mode = atoi(argv[2]);
617         if (fd < 0 || fd > 1024) {
618                 printf("fchmod: error=%d (file descriptor out of range)\n", EBADF);
619                 return NT_STATUS_OK;
620         }
621         if (vfs->files[fd] == NULL) {
622                 printf("fchmod: error=%d (invalid file descriptor)\n", EBADF);
623                 return NT_STATUS_OK;
624         }
625
626         if (vfs->conn->vfs_ops.fchmod(vfs->files[fd], fd, mode) == -1) {
627                 printf("fchmod: error=%d (%s)\n", errno, strerror(errno));
628                 return NT_STATUS_UNSUCCESSFUL;
629         }
630
631         printf("fchmod: ok\n");
632         return NT_STATUS_OK;
633 }
634
635
636 static NTSTATUS cmd_chown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
637 {
638         uid_t uid;
639         gid_t gid;
640         if (argc != 4) {
641                 printf("Usage: chown <path> <uid> <gid>\n");
642                 return NT_STATUS_OK;
643         }
644
645         uid = atoi(argv[2]);
646         gid = atoi(argv[3]);
647         if (vfs->conn->vfs_ops.chown(vfs->conn, argv[1], uid, gid) == -1) {
648                 printf("chown: error=%d (%s)\n", errno, strerror(errno));
649                 return NT_STATUS_UNSUCCESSFUL;
650         }
651
652         printf("chown: ok\n");
653         return NT_STATUS_OK;
654 }
655
656
657 static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
658 {
659         uid_t uid;
660         gid_t gid;
661         int fd;
662         if (argc != 4) {
663                 printf("Usage: fchown <fd> <uid> <gid>\n");
664                 return NT_STATUS_OK;
665         }
666
667         uid = atoi(argv[2]);
668         gid = atoi(argv[3]);
669         fd = atoi(argv[1]);
670         if (fd < 0 || fd > 1024) {
671                 printf("fchown: faliure=%d (file descriptor out of range)\n", EBADF);
672                 return NT_STATUS_OK;
673         }
674         if (vfs->files[fd] == NULL) {
675                 printf("fchown: error=%d (invalid file descriptor)\n", EBADF);
676                 return NT_STATUS_OK;
677         }
678         if (vfs->conn->vfs_ops.fchown(vfs->files[fd], fd, uid, gid) == -1) {
679                 printf("fchown error=%d (%s)\n", errno, strerror(errno));
680                 return NT_STATUS_UNSUCCESSFUL;
681         }
682
683         printf("fchown: ok\n");
684         return NT_STATUS_OK;
685 }
686
687
688 static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
689 {
690         char buf[PATH_MAX];
691         if (vfs->conn->vfs_ops.getwd(vfs->conn, buf) == NULL) {
692                 printf("getwd: error=%d (%s)\n", errno, strerror(errno));
693                 return NT_STATUS_UNSUCCESSFUL;
694         }
695
696         printf("getwd: %s\n", buf);
697         return NT_STATUS_OK;
698 }
699
700 static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
701 {
702         struct utimbuf times;
703         if (argc != 4) {
704                 printf("Usage: utime <path> <access> <modify>\n");
705                 return NT_STATUS_OK;
706         }
707         times.actime = atoi(argv[2]);
708         times.modtime = atoi(argv[3]);
709         if (vfs->conn->vfs_ops.utime(vfs->conn, argv[1], &times) != 0) {
710                 printf("utime: error=%d (%s)\n", errno, strerror(errno));
711                 return NT_STATUS_UNSUCCESSFUL;
712         }
713
714         printf("utime: ok\n");
715         return NT_STATUS_OK;
716 }
717
718 static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
719 {
720         int fd;
721         SMB_OFF_T off;
722         if (argc != 3) {
723                 printf("Usage: ftruncate <fd> <length>\n");
724                 return NT_STATUS_OK;
725         }
726
727         fd = atoi(argv[1]);
728         off = atoi(argv[2]);
729         if (fd < 0 || fd > 1024) {
730                 printf("ftruncate: error=%d (file descriptor out of range)\n", EBADF);
731                 return NT_STATUS_OK;
732         }
733         if (vfs->files[fd] == NULL) {
734                 printf("ftruncate: error=%d (invalid file descriptor)\n", EBADF);
735                 return NT_STATUS_OK;
736         }
737
738         if (vfs->conn->vfs_ops.ftruncate(vfs->files[fd], fd, off) == -1) {
739                 printf("ftruncate: error=%d (%s)\n", errno, strerror(errno));
740                 return NT_STATUS_UNSUCCESSFUL;
741         }
742
743         printf("ftruncate: ok\n");
744         return NT_STATUS_OK;
745 }
746
747 static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
748 {
749         printf("lock: Not yet implemented!\n");
750         return NT_STATUS_OK;
751 }
752
753 static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
754 {
755         if (argc != 3) {
756                 printf("Usage: symlink <path> <link>\n");
757                 return NT_STATUS_OK;
758         }
759
760         if (vfs->conn->vfs_ops.symlink(vfs->conn, argv[1], argv[2]) == -1) {
761                 printf("symlink: error=%d (%s)\n", errno, strerror(errno));
762                 return NT_STATUS_UNSUCCESSFUL;
763         }
764
765         printf("symlink: ok\n");
766         return NT_STATUS_OK;
767 }
768
769
770 static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
771 {
772         char buffer[PATH_MAX];
773         int size;
774
775         if (argc != 2) {
776                 printf("Usage: readlink <path>\n");
777                 return NT_STATUS_OK;
778         }
779
780         if ((size = vfs->conn->vfs_ops.readlink(vfs->conn, argv[1], buffer, PATH_MAX)) == -1) {
781                 printf("readlink: error=%d (%s)\n", errno, strerror(errno));
782                 return NT_STATUS_UNSUCCESSFUL;
783         }
784
785         buffer[size] = '\0';
786         printf("readlink: %s\n", buffer);
787         return NT_STATUS_OK;
788 }
789
790
791 static NTSTATUS cmd_link(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
792 {
793         if (argc != 3) {
794                 printf("Usage: link <path> <link>\n");
795                 return NT_STATUS_OK;
796         }
797
798         if (vfs->conn->vfs_ops.link(vfs->conn, argv[1], argv[2]) == -1) {
799                 printf("link: error=%d (%s)\n", errno, strerror(errno));
800                 return NT_STATUS_UNSUCCESSFUL;
801         }
802
803         printf("link: ok\n");
804         return NT_STATUS_OK;
805 }
806
807 static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
808 {
809         printf("lock: Not yet implemented!\n");
810         return NT_STATUS_OK;
811 }
812
813 static NTSTATUS cmd_realpath(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
814 {
815         char respath[PATH_MAX];
816         
817         if (argc != 2) {
818                 printf("Usage: realpath <path>\n");
819                 return NT_STATUS_OK;
820         }
821
822         if (vfs->conn->vfs_ops.realpath(vfs->conn, argv[1], respath) == NULL) {
823                 printf("realpath: error=%d (%s)\n", errno, strerror(errno));
824                 return NT_STATUS_UNSUCCESSFUL;
825         }
826
827         printf("realpath: ok\n");
828         return NT_STATUS_OK;
829 }
830
831 struct cmd_set vfs_commands[] = {
832
833         { "VFS Commands" },
834
835         { "load", cmd_load_module, "Load a module", "load <module.so>" },
836         { "populate", cmd_populate, "Populate a data buffer", "populate <char> <size>" },
837         { "showdata", cmd_show_data, "Show data currently in data buffer", "show_data [<offset> <len>]"},
838         { "connect",   cmd_connect,   "VFS connect()",    "connect" },
839         { "disconnect",   cmd_disconnect,   "VFS disconnect()",    "disconnect" },
840         { "disk_free",   cmd_disk_free,   "VFS disk_free()",    "disk_free <path>" },
841         { "opendir",   cmd_opendir,   "VFS opendir()",    "opendir <fname>" },
842         { "readdir",   cmd_readdir,   "VFS readdir()",    "readdir" },
843         { "mkdir",   cmd_mkdir,   "VFS mkdir()",    "mkdir <path>" },
844         { "rmdir",   cmd_pathfunc,   "VFS rmdir()",    "rmdir <path>" },
845         { "closedir",   cmd_closedir,   "VFS closedir()",    "closedir" },
846         { "open",   cmd_open,   "VFS open()",    "open <fname>" },
847         { "close",   cmd_close,   "VFS close()",    "close <fd>" },
848         { "read",   cmd_read,   "VFS read()",    "read <fd> <size>" },
849         { "write",   cmd_write,   "VFS write()",    "write <fd> <size>" },
850         { "lseek",   cmd_lseek,   "VFS lseek()",    "lseek <fd> <offset> <whence>" },
851         { "rename",   cmd_rename,   "VFS rename()",    "rename <old> <new>" },
852         { "fsync",   cmd_fsync,   "VFS fsync()",    "fsync <fd>" },
853         { "stat",   cmd_stat,   "VFS stat()",    "stat <fname>" },
854         { "fstat",   cmd_fstat,   "VFS fstat()",    "fstat <fd>" },
855         { "lstat",   cmd_lstat,   "VFS lstat()",    "lstat <fname>" },
856         { "unlink",   cmd_pathfunc,   "VFS unlink()",    "unlink <fname>" },
857         { "chmod",   cmd_chmod,   "VFS chmod()",    "chmod <path> <mode>" },
858         { "fchmod",   cmd_fchmod,   "VFS fchmod()",    "fchmod <fd> <mode>" },
859         { "chown",   cmd_chown,   "VFS chown()",    "chown <path> <uid> <gid>" },
860         { "fchown",   cmd_fchown,   "VFS fchown()",    "fchown <fd> <uid> <gid>" },
861         { "chdir",   cmd_pathfunc,   "VFS chdir()",    "chdir <path>" },
862         { "getwd",   cmd_getwd,   "VFS getwd()",    "getwd" },
863         { "utime",   cmd_utime,   "VFS utime()",    "utime <path> <access> <modify>" },
864         { "ftruncate",   cmd_ftruncate,   "VFS ftruncate()",    "ftruncate <fd> <length>" },
865         { "lock",   cmd_lock,   "VFS lock()",    "lock: Not yet implemented!" },
866         { "symlink",   cmd_symlink,   "VFS symlink()",    "symlink <old> <new>" },
867         { "readlink",   cmd_readlink,   "VFS readlink()",    "readlink <path>" },
868         { "link",   cmd_link,   "VFS link()",    "link <oldpath> <newpath>" },
869         { "mknod",   cmd_mknod,   "VFS mknod()",    "mknod: Not yet implemented!" },
870         { "realpath",   cmd_realpath,   "VFS realpath()",    "realpath <path>" },
871         { NULL }
872 };