static void do_setrattr(char *name, uint16 attr, int set) { uint16 oldattr; if (!cli_getatr(cli, name, &oldattr, NULL, NULL)) return; if (set == ATTRSET) { attr |= oldattr; } else { attr = oldattr & ~attr; } if (!cli_setatr(cli, name, attr, 0)) { DEBUG(1,("setatr failed: %s\n", cli_errstr(cli))); } }
/***************************************************** a wrapper for utime and utimes *******************************************************/ static int smbw_settime(const char *fname, time_t t) { struct smbw_server *srv; fstring server, share; pstring path; uint16 mode; if (!fname) { errno = EINVAL; return -1; } smbw_init(); smbw_busy++; /* work out what server they are after */ smbw_parse_path(fname, server, share, path); /* get a connection to the server */ srv = smbw_server(server, share); if (!srv) { /* smbw_server sets errno */ goto failed; } if (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) { errno = smbw_errno(&srv->cli); goto failed; } if (!cli_setatr(&srv->cli, path, mode, t)) { /* some servers always refuse directory changes */ if (!(mode & aDIR)) { errno = smbw_errno(&srv->cli); goto failed; } } smbw_busy--; return 0; failed: smbw_busy--; return -1; }
/***************************************************** a wrapper for chmod() *******************************************************/ int smbw_chmod(const char *fname, mode_t newmode) { struct smbw_server *srv; fstring server, share; pstring path; uint32 mode; if (!fname) { errno = EINVAL; return -1; } smbw_init(); smbw_busy++; /* work out what server they are after */ smbw_parse_path(fname, server, share, path); /* get a connection to the server */ srv = smbw_server(server, share); if (!srv) { /* smbw_server sets errno */ goto failed; } mode = 0; if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY; if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH; if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; if (!cli_setatr(&srv->cli, path, mode, 0)) { errno = smbw_errno(&srv->cli); goto failed; } smbw_busy--; return 0; failed: smbw_busy--; return -1; }
/* * Set file info on an SMB server. Use setpathinfo call first. If that * fails, use setattrE.. * * Access and modification time parameters are always used and must be * provided. Create time, if zero, will be determined from the actual create * time of the file. If non-zero, the create time will be set as well. * * "mode" (attributes) parameter may be set to -1 if it is not to be set. */ bool SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, time_t create_time, time_t access_time, time_t write_time, time_t change_time, uint16_t mode) { uint16_t fd; int ret; TALLOC_CTX *frame = talloc_stackframe(); /* * First, try setpathinfo (if qpathinfo succeeded), for it is the * modern function for "new code" to be using, and it works given a * filename rather than requiring that the file be opened to have its * attributes manipulated. */ if (srv->no_pathinfo || !NT_STATUS_IS_OK(cli_setpathinfo_basic(srv->cli, path, create_time, access_time, write_time, change_time, mode))) { /* * setpathinfo is not supported; go to plan B. * * cli_setatr() does not work on win98, and it also doesn't * support setting the access time (only the modification * time), so in all cases, we open the specified file and use * cli_setattrE() which should work on all OS versions, and * supports both times. */ /* Don't try {q,set}pathinfo() again, with this server */ srv->no_pathinfo = True; /* Open the file */ if (!NT_STATUS_IS_OK(cli_open(srv->cli, path, O_RDWR, DENY_NONE, &fd))) { errno = SMBC_errno(context, srv->cli); TALLOC_FREE(frame); return -1; } /* Set the new attributes */ ret = NT_STATUS_IS_OK(cli_setattrE(srv->cli, fd, change_time, access_time, write_time)); /* Close the file */ cli_close(srv->cli, fd); /* * Unfortunately, setattrE() doesn't have a provision for * setting the access mode (attributes). We'll have to try * cli_setatr() for that, and with only this parameter, it * seems to work on win98. */ if (ret && mode != (uint16_t) -1) { ret = NT_STATUS_IS_OK(cli_setatr(srv->cli, path, mode, 0)); } if (! ret) { errno = SMBC_errno(context, srv->cli); TALLOC_FREE(frame); return False; } } TALLOC_FREE(frame); return True; }