static VALUE rb_smbdir_read(VALUE self) { RB_SMBFILE_DATA_FROM_OBJ(self, data); RB_SMBFILE_DATA_CLOSED(data); smbc_readdir_fn fn; struct smbc_dirent *smbcdent; fn = smbc_getFunctionReaddir(data->smbcctx); errno = 0; smbcdent = (*fn)(data->smbcctx, data->smbcfile); if (smbcdent == NULL) { if (errno) { rb_sys_fail(data->url); } return Qnil; } VALUE args[4]; args[0] = rb_external_str_new_with_enc(smbcdent->name, strlen(smbcdent->name), data->enc); args[1] = INT2NUM(smbcdent->smbc_type); args[2] = rb_str_new2(data->url); rb_str_cat2(args[2], "/"); /* FIXME: Unless if the last char is not "/" */ rb_str_cat2(args[2], smbcdent->name); /* FIXME: Must be URL encoding */ args[3] = rb_str_new(smbcdent->comment, smbcdent->commentlen); VALUE entry_obj = rb_class_new_instance(4, args, rb_cSMBDirEntry); return entry_obj; }
int SmbFs::fs_readdir(const char *, void *buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info *fi) { QMutexLocker locker(&_mutex); smbc_dirent *ent; while((ent = (smbc_getFunctionReaddir(_ctx))(_ctx, (SMBCFILE *)fi->fh)) != NULL) { filler(buf,ent->name,0,0); } return(0); }
struct smbc_dirent * smbc_readdir(unsigned int dh) { SMBCFILE * file = find_fd(dh); return smbc_getFunctionReaddir(statcont)(statcont, file); }
static void list_dir (SMBCCTX *smb_context, const gchar *dirname, const gchar *path, GCancellable *cancellable, SMBData *data) { struct smbc_dirent *dirent; smbc_closedir_fn smbclient_closedir; smbc_readdir_fn smbclient_readdir; smbc_opendir_fn smbclient_opendir; PpPrintDevice *device; const gchar *host_name; SMBCFILE *dir; if (!g_cancellable_is_cancelled (cancellable)) { smbclient_closedir = smbc_getFunctionClosedir (smb_context); smbclient_readdir = smbc_getFunctionReaddir (smb_context); smbclient_opendir = smbc_getFunctionOpendir (smb_context); dir = smbclient_opendir (smb_context, dirname); if (!dir && errno == EACCES) { if (g_str_has_prefix (dirname, "smb://")) host_name = dirname + 6; else host_name = dirname; if (data->auth_if_needed) { data->cancelled = FALSE; smbc_setFunctionAuthDataWithContext (smb_context, auth_fn); dir = smbclient_opendir (smb_context, dirname); smbc_setFunctionAuthDataWithContext (smb_context, anonymous_auth_fn); if (data->cancelled) { device = g_object_new (PP_TYPE_PRINT_DEVICE, "host-name", host_name, "is-authenticated-server", TRUE, NULL); data->devices->devices = g_list_append (data->devices->devices, device); if (dir) smbclient_closedir (smb_context, dir); return; } } else { device = g_object_new (PP_TYPE_PRINT_DEVICE, "host-name", host_name, "is-authenticated-server", TRUE, NULL); data->devices->devices = g_list_append (data->devices->devices, device); } } while (dir && (dirent = smbclient_readdir (smb_context, dir))) { gchar *device_name; gchar *device_uri; gchar *subdirname = NULL; gchar *subpath = NULL; gchar *uri; if (dirent->smbc_type == SMBC_WORKGROUP) { subdirname = g_strdup_printf ("%s%s", dirname, dirent->name); subpath = g_strdup_printf ("%s%s", path, dirent->name); } if (dirent->smbc_type == SMBC_SERVER) { subdirname = g_strdup_printf ("smb://%s", dirent->name); subpath = g_strdup_printf ("%s//%s", path, dirent->name); } if (dirent->smbc_type == SMBC_PRINTER_SHARE) { uri = g_strdup_printf ("%s/%s", dirname, dirent->name); device_uri = g_uri_escape_string (uri, G_URI_RESERVED_CHARS_GENERIC_DELIMITERS G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS, FALSE); device_name = g_strdup (dirent->name); device_name = g_strcanon (device_name, ALLOWED_CHARACTERS, '-'); device = g_object_new (PP_TYPE_PRINT_DEVICE, "device-uri", device_uri, "is-network-device", TRUE, "device-info", dirent->comment, "device-name", device_name, "acquisition-method", data->hostname_set ? ACQUISITION_METHOD_SAMBA_HOST : ACQUISITION_METHOD_SAMBA, "device-location", path, "host-name", dirname, NULL); g_free (device_name); g_free (device_uri); g_free (uri); data->devices->devices = g_list_append (data->devices->devices, device); } if (subdirname) { list_dir (smb_context, subdirname, subpath, cancellable, data); g_free (subdirname); g_free (subpath); } } if (dir) smbclient_closedir (smb_context, dir); } }
static smbresultlist* browse(SMBCCTX *ctx, char *path, int maxdepth, int depth) { SMBCFILE *fd; struct smbc_dirent *dirent; char fullpath[2560] = ""; char acl[1024] = ""; int aclret; char mode[128] = ""; int moderet; smbresultlist *thisresults = NULL; smbresultlist *subresults = NULL; //Try and get a directory listing of the object we just opened. //This could be a workgroup, server, share, or directory and //we'll get the full listing. If it doesn't work, return our error. //Errors will happen a lot in normal usage due to access denied. if ((fd = smbc_getFunctionOpendir(ctx)(ctx, path)) == NULL) { smbresult *tmp = createSMBResultEmpty(); parse_smburl(path, &tmp->host, &tmp->share, &tmp->object); tmp->statuscode = errno; smbresultlist_push(&thisresults, tmp); return thisresults; } //Get the current entity of the directory item we're working on. while ((dirent = smbc_getFunctionReaddir(ctx)(ctx, fd)) != NULL) { smbresult *thisresult = createSMBResultEmpty(); //Check to see if what we're working on is blank, or one of the //special directory characters. If so, skip them. if(strcmp(dirent->name, "") == 0) continue; if(strcmp(dirent->name, ".") == 0) continue; if(strcmp(dirent->name, "..") == 0) continue; //Create the full path for this object by concating it with the //parent path. sprintf(fullpath, "%s/%s", path, dirent->name); //Parse out the various parts of the path for pretty output. parse_smburl(fullpath, &thisresult->host, &thisresult->share, &thisresult->object); //Set the type so we have it thisresult->type = dirent->smbc_type; //Get the "dos_attr.mode" extended attribute which is the file permissions. moderet = smbc_getFunctionGetxattr(ctx)(ctx, fullpath, "system.dos_attr.mode", &mode, sizeof(mode)); if(moderet == -1 && errno == 13) { thisresult->mode = -1; } else { //The ACL is returned as a string pointer, but we need to convert it to a long so we can //do binary comparison on the settings eventually. thisresult->mode = strtol(acl, NULL, 16); } //Get the ACL ACEs for the NTFS permissions. The + is so we lookup SIDs to names aclret = smbc_getFunctionGetxattr(ctx)(ctx, fullpath, "system.nt_sec_desc.acl.*+", acl, sizeof(acl)); if(aclret < 0) { char permerrbuf[100]; sprintf(permerrbuf, "Unable to pull permissions (%d): %s", errno, strerror(errno)); thisresult->acl = strdup(permerrbuf); thisresult->statuscode = errno; } else { thisresult->acl = strdup(acl); } smbresultlist_push(&thisresults, thisresult); //If we have a directory or share we want to recurse to our max depth if(depth < maxdepth) { switch (thisresult->type) { case SMBC_FILE_SHARE: case SMBC_DIR: subresults = browse(ctx, fullpath, maxdepth, depth++); smbresultlist_merge(&thisresults, &subresults); } } } //Try to close the directory that we had opened. If it failed, it'll return > 0. if(smbc_getFunctionClosedir(ctx)(ctx, fd) > 0) { smbresult *tmp = createSMBResultEmpty(); parse_smburl(path, &tmp->host, &tmp->share, &tmp->object); tmp->statuscode = errno; smbresultlist_push(&thisresults, tmp); } //Finally, we're done, lets return to the user. return thisresults; }