2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 static pstring smb_cwd;
29 struct smbw_server *next, *prev;
37 struct smbw_file *next, *prev;
41 struct smbw_server *srv;
45 struct smbw_dir *next, *prev;
47 int offset, count, malloced;
48 struct smbw_server *srv;
49 struct file_info *list;
52 static struct smbw_file *smbw_files;
53 static struct smbw_dir *smbw_dirs;
54 static struct smbw_server *smbw_srvs;
56 static struct bitmap *file_bmap;
57 static pstring local_machine;
58 extern int DEBUGLEVEL;
62 /*****************************************************
64 *******************************************************/
67 extern BOOL in_client;
68 static int initialised;
69 static pstring servicesf = CONFIGFILE;
73 if (initialised) return;
79 setup_logging("smbw",True);
83 if ((p=getenv("SMBW_LOGFILE"))) {
87 file_bmap = bitmap_allocate(SMBW_MAX_OPEN);
96 if (!lp_load(servicesf,True,False,False)) {
100 get_myname(local_machine,NULL);
102 if ((p=getenv("SMBW_DEBUG"))) {
103 DEBUGLEVEL = atoi(p);
106 if ((p=getenv(SMBW_PWD_ENV))) {
108 DEBUG(4,("Initial cwd from smb_cwd is %s\n", smb_cwd));
111 DEBUG(4,("Initial cwd from getwd is %s\n", smb_cwd));
116 /*****************************************************
117 determine if a file descriptor is a smb one
118 *******************************************************/
121 if (smbw_busy) return False;
122 return (fd >= SMBW_FD_OFFSET);
125 /*****************************************************
126 a crude inode number generator
127 *******************************************************/
128 ino_t smbw_inode(const char *name)
130 return (ino_t)str_checksum(name);
133 /*****************************************************
134 remove redundent stuff from a filename
135 *******************************************************/
136 void clean_fname(char *name)
147 DEBUG(5,("cleaning %s\n", name));
149 if ((p=strstr(name,"/./"))) {
157 if ((p=strstr(name,"//"))) {
165 if (strcmp(name,"/../")==0) {
170 if ((p=strstr(name,"/../"))) {
172 for (p2=(p>name?p-1:p);p2>name;p2--) {
173 if (p2[0] == '/') break;
181 if (strcmp(name,"/..")==0) {
187 p = l>=3?(name+l-3):name;
188 if (strcmp(p,"/..")==0) {
190 for (p2=p-1;p2>name;p2--) {
191 if (p2[0] == '/') break;
202 p = l>=2?(name+l-2):name;
203 if (strcmp(p,"/.")==0) {
211 if (strncmp(p=name,"./",2) == 0) {
219 if (l > 1 && p[l-1] == '/') {
227 /*****************************************************
228 parse a smb path into its components.
229 *******************************************************/
230 char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
236 *server = *share = *path = 0;
238 if (fname[0] == '/') {
241 slprintf(s,sizeof(s)-1, "%s/%s", smb_cwd, fname);
245 DEBUG(5,("cleaned %s (fname=%s cwd=%s)\n",
248 if (strncmp(s,SMBW_PREFIX,strlen(SMBW_PREFIX))) return s;
250 p = s + strlen(SMBW_PREFIX);
259 len = MIN(len,sizeof(fstring)-1);
261 strncpy(server, p, len);
266 fstrcpy(share,"IPC$");
280 len = MIN(len,sizeof(fstring)-1);
282 strncpy(share, p, len);
293 string_sub(path, "/", "\\");
296 DEBUG(5,("parsed path name=%s cwd=%s [%s] [%s] [%s]\n",
298 server, share, path));
303 /*****************************************************
304 determine if a path name (possibly relative) is in the
306 *******************************************************/
307 BOOL smbw_path(const char *path)
309 fstring server, share;
312 int l=strlen(SMBW_PREFIX)-1;
314 if (path[0] == '/' && strncmp(path,SMBW_PREFIX,l)) {
318 if (smbw_busy) return False;
322 DEBUG(3,("smbw_path(%s)\n", path));
324 cwd = smbw_parse_path(path, server, share, s);
326 if (strncmp(cwd,SMBW_PREFIX,l) == 0 &&
327 (cwd[l] == '/' || cwd[l] == 0)) {
334 /*****************************************************
335 return a unix errno from a SMB error pair
336 *******************************************************/
337 int smbw_errno(struct cli_state *c)
343 ret = cli_error(c, &eclass, &ecode);
346 DEBUG(3,("smbw_error %d %d (0x%x)\n",
347 (int)eclass, (int)ecode, (int)ecode));
352 /*****************************************************
353 return a connection to a server (existing or new)
354 *******************************************************/
355 struct smbw_server *smbw_server(char *server, char *share)
357 struct smbw_server *srv=NULL;
358 static struct cli_state c;
362 struct nmb_name called, calling;
364 username = getenv("SMBW_USER");
365 if (!username) username = getenv("USER");
366 if (!username) username = "guest";
368 workgroup = getenv("SMBW_WORKGROUP");
369 if (!workgroup) workgroup = lp_workgroup();
371 password = getenv("SMBW_PASSWORD");
372 if (!password) password = "";
374 /* try to use an existing connection */
375 for (srv=smbw_srvs;srv;srv=srv->next) {
376 if (strcmp(server,srv->server_name)==0 &&
377 strcmp(share,srv->share_name)==0) return srv;
380 if (server[0] == 0) {
385 /* have to open a new connection */
386 if (!cli_initialise(&c) || !cli_connect(&c, server, NULL)) {
391 make_nmb_name(&calling, local_machine, 0x0, "");
392 make_nmb_name(&called , server, 0x20, "");
394 if (!cli_session_request(&c, &calling, &called)) {
400 if (!cli_negprot(&c)) {
406 if (!cli_session_setup(&c, username,
407 password, strlen(password),
408 password, strlen(password),
415 if (!cli_send_tconX(&c, share,
416 strstr(share,"IPC$")?"IPC":"A:",
417 password, strlen(password)+1)) {
418 errno = smbw_errno(&c);
423 srv = (struct smbw_server *)malloc(sizeof(*srv));
433 srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
435 srv->server_name = strdup(server);
436 if (!srv->server_name) {
441 srv->share_name = strdup(share);
442 if (!srv->share_name) {
447 /* some programs play with file descriptors fairly intimately. We
448 try to get out of the way by duping to a high fd number */
449 if (fcntl(SMBW_CLI_FD + srv->cli.fd, F_GETFD) && errno == EBADF) {
450 if (dup2(srv->cli.fd,SMBW_CLI_FD+srv->cli.fd) ==
451 srv->cli.fd+SMBW_CLI_FD) {
453 srv->cli.fd += SMBW_CLI_FD;
457 DLIST_ADD(smbw_srvs, srv);
463 if (!srv) return NULL;
465 if (srv->server_name) free(srv->server_name);
466 if (srv->share_name) free(srv->share_name);
472 /*****************************************************
473 map a fd to a smbw_file structure
474 *******************************************************/
475 struct smbw_file *smbw_file(int fd)
477 struct smbw_file *file;
479 for (file=smbw_files;file;file=file->next) {
480 if (file->fd == fd) return file;
485 /*****************************************************
486 map a fd to a smbw_dir structure
487 *******************************************************/
488 struct smbw_dir *smbw_dir(int fd)
490 struct smbw_dir *dir;
492 for (dir=smbw_dirs;dir;dir=dir->next) {
493 if (dir->fd == fd) return dir;
498 /*****************************************************
499 setup basic info in a stat structure
500 *******************************************************/
501 void smbw_setup_stat(struct stat *st, char *fname, size_t size, int mode)
505 if (IS_DOS_DIR(mode)) {
506 st->st_mode = SMBW_DIR_MODE;
508 st->st_mode = SMBW_FILE_MODE;
512 st->st_blksize = 512;
513 st->st_blocks = (size+511)/512;
514 st->st_uid = getuid();
515 st->st_gid = getgid();
516 st->st_ino = smbw_inode(fname);
520 /*****************************************************
521 try to do a QPATHINFO and if that fails then do a getatr
522 this is needed because win95 sometimes refuses the qpathinfo
523 *******************************************************/
524 static BOOL smbw_getatr(struct smbw_server *srv, char *path,
525 uint32 *mode, size_t *size,
526 time_t *c_time, time_t *a_time, time_t *m_time)
528 if (cli_qpathinfo(&srv->cli, path, c_time, a_time, m_time,
529 size, mode)) return True;
531 /* if this is NT then don't bother with the getatr */
532 if (srv->cli.capabilities & CAP_NT_SMBS) return False;
534 if (cli_getatr(&srv->cli, path, mode, size, m_time)) {
535 a_time = c_time = m_time;
541 /*****************************************************
542 free a smbw_dir structure and all entries
543 *******************************************************/
544 static void free_dir(struct smbw_dir *dir)
554 static struct smbw_dir *cur_dir;
556 /*****************************************************
557 add a entry to a directory listing
558 *******************************************************/
559 void smbw_dir_add(struct file_info *finfo)
561 DEBUG(5,("%s\n", finfo->name));
563 if (cur_dir->malloced == cur_dir->count) {
564 cur_dir->list = (struct file_info *)Realloc(cur_dir->list,
565 sizeof(cur_dir->list[0])*
566 (cur_dir->count+100));
567 if (!cur_dir->list) {
571 cur_dir->malloced += 100;
574 cur_dir->list[cur_dir->count] = *finfo;
578 /*****************************************************
579 add a entry to a directory listing
580 *******************************************************/
581 void smbw_share_add(const char *share, uint32 type, const char *comment)
583 struct file_info finfo;
587 pstrcpy(finfo.name, share);
588 finfo.mode = aRONLY | aDIR;
590 smbw_dir_add(&finfo);
594 /*****************************************************
595 open a directory on the server
596 *******************************************************/
597 int smbw_dir_open(const char *fname, int flags)
599 fstring server, share;
601 struct smbw_server *srv=NULL;
602 struct smbw_dir *dir=NULL;
606 DEBUG(4,("%s\n", __FUNCTION__));
615 /* work out what server they are after */
616 smbw_parse_path(fname, server, share, path);
618 DEBUG(4,("dir_open share=%s\n", share));
620 /* get a connection to the server */
621 srv = smbw_server(server, share);
623 /* smbw_server sets errno */
627 dir = (struct smbw_dir *)malloc(sizeof(*dir));
637 slprintf(mask, sizeof(mask)-1, "%s\\*", path);
638 string_sub(mask,"\\\\","\\");
640 if (strcmp(share,"IPC$") == 0) {
641 DEBUG(4,("doing NetShareEnum\n"));
642 if (cli_RNetShareEnum(&srv->cli, smbw_share_add) <= 0) {
643 errno = smbw_errno(&srv->cli);
647 if (cli_list(&srv->cli, mask, aHIDDEN|aSYSTEM|aDIR,
648 smbw_dir_add) <= 0) {
649 errno = smbw_errno(&srv->cli);
656 fd = bitmap_find(file_bmap, 0);
662 DLIST_ADD(smbw_dirs, dir);
664 bitmap_set(file_bmap, fd);
666 dir->fd = fd + SMBW_FD_OFFSET;
669 DEBUG(4,(" -> %d\n", dir->count));
682 /*****************************************************
684 *******************************************************/
685 int smbw_open(const char *fname, int flags, mode_t mode)
687 fstring server, share;
689 struct smbw_server *srv=NULL;
691 struct smbw_file *file=NULL;
693 DEBUG(4,("%s\n", __FUNCTION__));
704 /* work out what server they are after */
705 smbw_parse_path(fname, server, share, path);
707 /* get a connection to the server */
708 srv = smbw_server(server, share);
710 /* smbw_server sets errno */
714 if (path[strlen(path)-1] == '\\') {
717 fd = cli_open(&srv->cli, path, flags, DENY_NONE);
720 /* it might be a directory. Maybe we should use chkpath? */
721 fd = smbw_dir_open(fname, flags);
730 file = (struct smbw_file *)malloc(sizeof(*file));
739 file->fname = strdup(path);
745 file->fd = bitmap_find(file_bmap, 0);
747 if (file->fd == -1) {
752 bitmap_set(file_bmap, file->fd);
754 file->fd += SMBW_FD_OFFSET;
756 DLIST_ADD(smbw_files, file);
758 DEBUG(4,("opened %s\n", fname));
765 cli_close(&srv->cli, fd);
778 /*****************************************************
779 a wrapper for fstat() on a directory
780 *******************************************************/
781 int smbw_dir_fstat(int fd, struct stat *st)
783 struct smbw_dir *dir;
785 DEBUG(4,("%s\n", __FUNCTION__));
795 smbw_setup_stat(st, "", dir->count*sizeof(struct dirent), aDIR);
797 st->st_dev = dir->srv->dev;
802 /*****************************************************
803 a wrapper for fstat()
804 *******************************************************/
805 int smbw_fstat(int fd, struct stat *st)
807 struct smbw_file *file;
808 time_t c_time, a_time, m_time;
812 DEBUG(4,("%s\n", __FUNCTION__));
816 file = smbw_file(fd);
818 int ret = smbw_dir_fstat(fd, st);
823 if (!cli_qfileinfo(&file->srv->cli, file->cli_fd,
824 &mode, &size, &c_time, &a_time, &m_time) &&
825 !cli_getattrE(&file->srv->cli, file->cli_fd,
826 &mode, &size, &c_time, &a_time, &m_time)) {
832 smbw_setup_stat(st, file->fname, size, mode);
834 st->st_atime = a_time;
835 st->st_ctime = c_time;
836 st->st_mtime = m_time;
837 st->st_dev = file->srv->dev;
839 DEBUG(4,("%s - OK\n", __FUNCTION__));
846 /*****************************************************
848 *******************************************************/
849 int smbw_stat(const char *fname, struct stat *st)
851 struct smbw_server *srv;
852 fstring server, share;
854 time_t m_time=0, a_time=0, c_time=0;
858 DEBUG(4,("%s (%s)\n", __FUNCTION__, fname));
869 /* work out what server they are after */
870 smbw_parse_path(fname, server, share, path);
872 /* get a connection to the server */
873 srv = smbw_server(server, share);
875 /* smbw_server sets errno */
879 if (strcmp(share,"IPC$") == 0) {
880 mode = aDIR | aRONLY;
882 if (!smbw_getatr(srv, path,
883 &mode, &size, &c_time, &a_time, &m_time)) {
884 errno = smbw_errno(&srv->cli);
889 smbw_setup_stat(st, path, size, mode);
891 st->st_atime = time(NULL);
892 st->st_ctime = m_time;
893 st->st_mtime = m_time;
894 st->st_dev = srv->dev;
904 /*****************************************************
906 *******************************************************/
907 ssize_t smbw_read(int fd, void *buf, size_t count)
909 struct smbw_file *file;
912 DEBUG(4,("%s %d\n", __FUNCTION__, (int)count));
916 file = smbw_file(fd);
923 ret = cli_read(&file->srv->cli, file->cli_fd, buf, file->offset, count);
926 errno = smbw_errno(&file->srv->cli);
937 /*****************************************************
938 a wrapper for write()
939 *******************************************************/
940 ssize_t smbw_write(int fd, void *buf, size_t count)
942 struct smbw_file *file;
945 DEBUG(4,("%s\n", __FUNCTION__));
949 file = smbw_file(fd);
951 DEBUG(3,("bad fd in read\n"));
957 ret = cli_write(&file->srv->cli, file->cli_fd, buf, file->offset, count);
960 errno = smbw_errno(&file->srv->cli);
971 /*****************************************************
972 close a directory handle
973 *******************************************************/
974 int smbw_dir_close(int fd)
976 struct smbw_dir *dir;
978 DEBUG(4,("%s\n", __FUNCTION__));
982 DEBUG(4,("%s(%d)\n", __FUNCTION__, __LINE__));
987 bitmap_clear(file_bmap, dir->fd - SMBW_FD_OFFSET);
989 DLIST_REMOVE(smbw_dirs, dir);
996 /*****************************************************
997 a wrapper for close()
998 *******************************************************/
999 int smbw_close(int fd)
1001 struct smbw_file *file;
1003 DEBUG(4,("%s\n", __FUNCTION__));
1007 file = smbw_file(fd);
1009 int ret = smbw_dir_close(fd);
1014 if (!cli_close(&file->srv->cli, file->cli_fd)) {
1015 errno = smbw_errno(&file->srv->cli);
1021 bitmap_clear(file_bmap, file->fd - SMBW_FD_OFFSET);
1023 DLIST_REMOVE(smbw_files, file);
1035 /*****************************************************
1036 a wrapper for fcntl()
1037 *******************************************************/
1038 int smbw_fcntl(int fd, int cmd, long arg)
1040 DEBUG(4,("%s\n", __FUNCTION__));
1045 /*****************************************************
1046 a wrapper for getdents()
1047 *******************************************************/
1048 int smbw_getdents(unsigned int fd, struct dirent *dirp, int count)
1050 struct smbw_dir *dir;
1053 DEBUG(4,("%s\n", __FUNCTION__));
1064 while (count>=sizeof(*dirp) && (dir->offset < dir->count)) {
1065 dirp->d_off = (dir->offset+1)*sizeof(*dirp);
1066 dirp->d_reclen = sizeof(*dirp);
1067 /* what's going on with the -1 here? maybe d_type
1068 isn't really there? */
1069 safe_strcpy(&dirp->d_name[-1], dir->list[dir->offset].name,
1070 sizeof(dirp->d_name)-1);
1071 dirp->d_ino = smbw_inode(dir->list[dir->offset].name);
1073 count -= dirp->d_reclen;
1074 if (dir->offset == dir->count) {
1082 return n*sizeof(*dirp);
1086 /*****************************************************
1087 a wrapper for access()
1088 *******************************************************/
1089 int smbw_access(const char *name, int mode)
1092 /* how do we map this properly ?? */
1093 return smbw_stat(name, &st);
1096 /*****************************************************
1097 a wrapper for realink() - needed for correct errno setting
1098 *******************************************************/
1099 int smbw_readlink(const char *path, char *buf, size_t bufsize)
1104 ret = smbw_stat(path, &st);
1106 DEBUG(4,("readlink(%s) failed\n", path));
1110 /* it exists - say it isn't a link */
1111 DEBUG(4,("readlink(%s) not a link\n", path));
1118 /*****************************************************
1119 a wrapper for chdir()
1120 *******************************************************/
1121 int smbw_chdir(const char *name)
1123 struct smbw_server *srv;
1124 fstring server, share;
1131 if (smbw_busy) return real_chdir(cwd);
1140 DEBUG(4,("%s (%s)\n", __FUNCTION__, name));
1142 /* work out what server they are after */
1143 cwd = smbw_parse_path(name, server, share, path);
1145 if (strncmp(cwd,SMBW_PREFIX,strlen(SMBW_PREFIX))) {
1146 if (real_chdir(cwd) == 0) {
1147 DEBUG(4,("set SMBW_CWD to %s\n", cwd));
1148 pstrcpy(smb_cwd, cwd);
1149 if (setenv(SMBW_PWD_ENV, smb_cwd, 1)) {
1150 DEBUG(4,("setenv failed\n"));
1158 /* get a connection to the server */
1159 srv = smbw_server(server, share);
1161 /* smbw_server sets errno */
1165 if (strcmp(share,"IPC$") &&
1166 !smbw_getatr(srv, path,
1167 &mode, NULL, NULL, NULL, NULL)) {
1168 errno = smbw_errno(&srv->cli);
1172 if (!(mode & aDIR)) {
1177 DEBUG(4,("set SMBW_CWD2 to %s\n", cwd));
1178 pstrcpy(smb_cwd, cwd);
1179 if (setenv(SMBW_PWD_ENV, smb_cwd, 1)) {
1180 DEBUG(4,("setenv failed\n"));
1183 /* we don't want the old directory to be busy */
1196 /*****************************************************
1197 a wrapper for unlink()
1198 *******************************************************/
1199 int smbw_unlink(const char *fname)
1201 struct smbw_server *srv;
1202 fstring server, share;
1205 DEBUG(4,("%s (%s)\n", __FUNCTION__, fname));
1216 /* work out what server they are after */
1217 smbw_parse_path(fname, server, share, path);
1219 /* get a connection to the server */
1220 srv = smbw_server(server, share);
1222 /* smbw_server sets errno */
1226 if (!cli_unlink(&srv->cli, path)) {
1227 errno = smbw_errno(&srv->cli);
1240 /*****************************************************
1241 a wrapper for rename()
1242 *******************************************************/
1243 int smbw_rename(const char *oldname, const char *newname)
1245 struct smbw_server *srv;
1246 fstring server1, share1;
1248 fstring server2, share2;
1251 DEBUG(4,("%s (%s, %s)\n", __FUNCTION__, oldname, newname));
1253 if (!oldname || !newname) {
1262 /* work out what server they are after */
1263 smbw_parse_path(oldname, server1, share1, path1);
1264 smbw_parse_path(newname, server2, share2, path2);
1266 if (strcmp(server1, server2) || strcmp(share1, share2)) {
1267 /* can't cross filesystems */
1272 /* get a connection to the server */
1273 srv = smbw_server(server1, share1);
1275 /* smbw_server sets errno */
1279 if (!cli_rename(&srv->cli, path1, path2)) {
1280 errno = smbw_errno(&srv->cli);
1293 /*****************************************************
1294 a wrapper for utime()
1295 *******************************************************/
1296 int smbw_utime(const char *fname, struct utimbuf *buf)
1298 struct smbw_server *srv;
1299 fstring server, share;
1303 DEBUG(4,("%s (%s)\n", __FUNCTION__, fname));
1314 /* work out what server they are after */
1315 smbw_parse_path(fname, server, share, path);
1317 /* get a connection to the server */
1318 srv = smbw_server(server, share);
1320 /* smbw_server sets errno */
1324 if (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) {
1325 errno = smbw_errno(&srv->cli);
1329 if (!cli_setatr(&srv->cli, path, mode, buf->modtime)) {
1330 errno = smbw_errno(&srv->cli);
1342 /*****************************************************
1343 a wrapper for chown()
1344 *******************************************************/
1345 int smbw_chown(const char *fname, uid_t owner, gid_t group)
1347 struct smbw_server *srv;
1348 fstring server, share;
1352 DEBUG(4,("%s (%s)\n", __FUNCTION__, fname));
1363 /* work out what server they are after */
1364 smbw_parse_path(fname, server, share, path);
1366 /* get a connection to the server */
1367 srv = smbw_server(server, share);
1369 /* smbw_server sets errno */
1373 if (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) {
1374 errno = smbw_errno(&srv->cli);
1378 /* assume success */
1388 /*****************************************************
1389 a wrapper for chmod()
1390 *******************************************************/
1391 int smbw_chmod(const char *fname, mode_t newmode)
1393 struct smbw_server *srv;
1394 fstring server, share;
1398 DEBUG(4,("%s (%s)\n", __FUNCTION__, fname));
1409 /* work out what server they are after */
1410 smbw_parse_path(fname, server, share, path);
1412 /* get a connection to the server */
1413 srv = smbw_server(server, share);
1415 /* smbw_server sets errno */
1419 if (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) {
1420 errno = smbw_errno(&srv->cli);
1424 /* assume success for the moment - need to add attribute mapping */
1435 /*****************************************************
1436 a wrapper for lseek() on directories
1437 *******************************************************/
1438 off_t smbw_dir_lseek(int fd, off_t offset, int whence)
1440 struct smbw_dir *dir;
1443 DEBUG(4,("%s offset=%d whence=%d\n", __FUNCTION__,
1444 (int)offset, whence));
1454 dir->offset = offset/sizeof(struct dirent);
1457 dir->offset += offset/sizeof(struct dirent);
1460 dir->offset = (dir->count * sizeof(struct dirent)) + offset;
1461 dir->offset /= sizeof(struct dirent);
1465 ret = dir->offset * sizeof(struct dirent);
1467 DEBUG(4,(" -> %d\n", (int)ret));
1472 /*****************************************************
1473 a wrapper for lseek()
1474 *******************************************************/
1475 off_t smbw_lseek(int fd, off_t offset, int whence)
1477 struct smbw_file *file;
1480 DEBUG(4,("%s\n", __FUNCTION__));
1484 file = smbw_file(fd);
1486 off_t ret = smbw_dir_lseek(fd, offset, whence);
1493 file->offset = offset;
1496 file->offset += offset;
1499 if (!cli_qfileinfo(&file->srv->cli, file->cli_fd,
1500 NULL, &size, NULL, NULL, NULL) &&
1501 !cli_getattrE(&file->srv->cli, file->cli_fd,
1502 NULL, &size, NULL, NULL, NULL)) {
1507 file->offset = size + offset;
1512 return file->offset;
1516 /*****************************************************
1517 a wrapper for mkdir()
1518 *******************************************************/
1519 int smbw_mkdir(const char *fname, mode_t mode)
1521 struct smbw_server *srv;
1522 fstring server, share;
1525 DEBUG(4,("%s (%s)\n", __FUNCTION__, fname));
1536 /* work out what server they are after */
1537 smbw_parse_path(fname, server, share, path);
1539 /* get a connection to the server */
1540 srv = smbw_server(server, share);
1542 /* smbw_server sets errno */
1546 if (!cli_mkdir(&srv->cli, path)) {
1547 errno = smbw_errno(&srv->cli);
1559 /*****************************************************
1560 a wrapper for rmdir()
1561 *******************************************************/
1562 int smbw_rmdir(const char *fname)
1564 struct smbw_server *srv;
1565 fstring server, share;
1568 DEBUG(4,("%s (%s)\n", __FUNCTION__, fname));
1579 /* work out what server they are after */
1580 smbw_parse_path(fname, server, share, path);
1582 /* get a connection to the server */
1583 srv = smbw_server(server, share);
1585 /* smbw_server sets errno */
1589 if (!cli_rmdir(&srv->cli, path)) {
1590 errno = smbw_errno(&srv->cli);
1603 /*****************************************************
1604 a wrapper for getcwd()
1605 *******************************************************/
1606 char *smbw_getcwd(char *buf, size_t size)
1611 return __getcwd(buf, size);
1617 if (size <= 0) size = strlen(smb_cwd)+1;
1618 buf = (char *)malloc(size);
1626 if (strlen(smb_cwd) > size-1) {
1632 safe_strcpy(buf, smb_cwd, size);