darwin_clone_local_volumes.c [plain text]
#include "includes.h"
#include "smb_macros.h"
#include <sys/attr.h>
#define APPLE_SLASH_VOLUMES "/Volumes"
static void get_volume_name(const char *path, char *volname)
{
struct attrlist attrlist;
char attrbuf[sizeof(struct attrreference) + sizeof(u_int32_t) + NAME_MAX + 1];
struct attrreference * data = (struct attrreference *)attrbuf;
u_int32_t *nmlen;
char *name = NULL;
int len, maxlen;
ZERO_STRUCT(attrlist);
ZERO_STRUCT(attrbuf);
attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
attrlist.commonattr = ATTR_CMN_NAME;
if (getattrlist(path, &attrlist, attrbuf, sizeof(attrbuf), 0) != 0) {
DEBUG(5, ("getattrlist for %s failed: %s\n", path, strerror(errno)));
return;
}
maxlen = data->attr_dataoffset - (sizeof(struct attrreference) + sizeof(u_int32_t));
nmlen = (u_int32_t *)(attrbuf+sizeof(struct attrreference));
if (*nmlen > maxlen) {
DEBUG(5, ("name length to large for buffer nmlen=%u maxlen=%u\n",
(unsigned)nmlen, (unsigned)maxlen));
return;
}
len = *nmlen++;
name = (char *)nmlen;
strlcpy(volname, name, NAME_MAX + 1);
return;
}
static int add_admin_volume(const char * name, const char * path)
{
int snum;
snum = lp_servicenumber(name);
if (VALID_SNUM(snum)) {
return snum;
}
snum = lp_add_default_service(name);
if (!VALID_SNUM(snum)) {
return -1;
}
lp_do_parameter(snum, "path", path);
lp_do_parameter(snum, "valid users", "+BUILTIN\\Administrators");
lp_do_parameter(snum, "read only", "no");
return snum;
}
int apple_clone_local_volumes(const char * svcname)
{
struct statfs *sb, *stat_p = NULL;
int n = getfsstat(NULL, 0, MNT_NOWAIT);
char volname[NAME_MAX + 1];
int ii;
if (n <= 0)
goto out;
stat_p = (struct statfs *)SMB_MALLOC(n * sizeof(*stat_p));
if (stat_p == NULL)
goto out;
if (getfsstat(stat_p, n * sizeof(*stat_p), MNT_NOWAIT) <= 0)
goto out;
sb = stat_p;
for (ii = 0; ii < n; ii++, sb++) {
if (!(sb->f_flags & MNT_LOCAL)) {
continue;
}
if (sb->f_flags & MNT_DONTBROWSE) {
continue;
}
if (strncmp(sb->f_mntonname, "/", 2) == 0) {
continue;
}
if (strncmp(sb->f_mntonname, APPLE_SLASH_VOLUMES,
strlen(APPLE_SLASH_VOLUMES)) == 0) {
int snum;
get_volume_name(sb->f_mntonname, volname);
if (svcname && !strequal(svcname, volname)) {
continue;
}
snum = add_admin_volume(volname, sb->f_mntonname);
if (VALID_SNUM(snum)) {
DEBUG(5,("Sharing %s with path = %s\n",
volname, sb->f_mntonname));
} else {
DEBUG(5,("Failed to share %s with path = %s\n",
volname, sb->f_mntonname));
}
if (svcname) {
return snum;
}
}
}
out:
SAFE_FREE(stat_p);
return GLOBAL_SECTION_SNUM;
}