1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

libsmb: Implement smbc_notify

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>

Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Fri Jul 10 09:35:13 CEST 2015 on sn-devel-104
This commit is contained in:
Volker Lendecke 2015-06-26 13:36:43 +02:00 committed by Jeremy Allison
parent b1ea9856e0
commit 8a58a48f86
10 changed files with 609 additions and 1 deletions

View File

@ -0,0 +1,78 @@
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <libsmbclient.h>
#include <inttypes.h>
#include "get_auth_data_fn.h"
static int notify_cb(const struct smbc_notify_callback_action *actions,
size_t num_actions, void *private_data)
{
int *count = private_data;
size_t i;
printf("%zu\n", num_actions);
for (i=0; i<num_actions; i++) {
const struct smbc_notify_callback_action *a = &actions[i];
printf("%s: %"PRIu32"\n", a->filename, a->action);
}
*count -= 1;
if (*count < 0) {
return 1;
}
return 0;
}
int main(int argc, char * argv[])
{
int fd;
int ret;
int debug = 0;
int saved_errno;
char path[2048];
char * p;
int count = 1000;
smbc_init(get_auth_data_fn, debug);
fprintf(stdout, "Path: ");
*path = '\0';
fgets(path, sizeof(path) - 1, stdin);
if (strlen(path) == 0) {
return 0;
}
p = path + strlen(path) - 1;
if (*p == '\n') {
*p = '\0';
}
fd = smbc_opendir(path);
if (fd < 0) {
perror("smbc_open");
return 1;
}
ret = smbc_notify(fd, 1,
SMBC_NOTIFY_CHANGE_SECURITY|
SMBC_NOTIFY_CHANGE_FILE_NAME,
1000, notify_cb, &count);
if (ret < 0) {
saved_errno = errno;
}
smbc_close(fd);
if (ret < 0) {
errno = saved_errno;
perror("notify");
}
return 0;
}

View File

@ -6,6 +6,7 @@ names = ['testsmbc',
'testacl3',
'testbrowse',
'testbrowse2',
'testnotify',
'teststat',
'teststat2',
'teststat3',

View File

@ -247,6 +247,7 @@ struct SMBC_internal_data {
struct
{
smbc_splice_fn splice_fn;
smbc_notify_fn notify_fn;
} smb;
uint16_t port;
@ -344,6 +345,12 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
SMBCCTX *ncontext,
const char *nname);
int
SMBC_notify_ctx(SMBCCTX *c, SMBCFILE *dir, smbc_bool recursive,
uint32_t completion_filter, unsigned callback_timeout_ms,
smbc_notify_callback_fn cb, void *private_data);
/* Functions in libsmb_file.c */
SMBCFILE *

View File

@ -993,6 +993,30 @@ typedef int (*smbc_fstatdir_fn)(SMBCCTX *c,
smbc_fstatdir_fn smbc_getFunctionFstatdir(SMBCCTX *c);
void smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn);
#define SMBC_NOTIFY_ACTION_ADDED 1
#define SMBC_NOTIFY_ACTION_REMOVED 2
#define SMBC_NOTIFY_ACTION_MODIFIED 3
#define SMBC_NOTIFY_ACTION_OLD_NAME 4
#define SMBC_NOTIFY_ACTION_NEW_NAME 5
#define SMBC_NOTIFY_ACTION_ADDED_STREAM 6
#define SMBC_NOTIFY_ACTION_REMOVED_STREAM 7
#define SMBC_NOTIFY_ACTION_MODIFIED_STREAM 8
struct smbc_notify_callback_action {
uint32_t action;
const char *filename;
};
typedef int (*smbc_notify_callback_fn)(
const struct smbc_notify_callback_action *actions,
size_t num_actions, void *private_data);
typedef int (*smbc_notify_fn)(SMBCCTX *c, SMBCFILE *dir, smbc_bool recursive,
uint32_t completion_filter,
unsigned callback_timeout_ms,
smbc_notify_callback_fn cb, void *private_data);
smbc_notify_fn smbc_getFunctionNotify(SMBCCTX *c);
void smbc_setFunctionNotify(SMBCCTX *c, smbc_notify_fn fn);
/*****************************************************************
@ -1620,6 +1644,47 @@ int smbc_mkdir(const char *durl, mode_t mode);
*/
int smbc_rmdir(const char *durl);
/**@ingroup directory
* Request directory notifications
*
* @param dh Valid directory as returned by smbc_opendir()
*
* @param recursive Are changes in subdirectories wanted?
*
* @param completion_filter Bitwise-or of the SMBC_NOTIFY_CHANGE_*
* events that are interesting
*
* @param callback_timeout_ms If set to non-zero, interval in milliseconds
* that "cb" will be called with 0 actions.
* This gives "cb" the chance to cancel the
* smbc_notify call.
*
* @param cb Callback functions taking events. If "cb"
* returns nonzero, smbc_notify will return.
*
* @param private_data Pointer given to "cb"
*
* @return 0 on success, -1 on error with errno set
*
* @see smbc_opendir(), smbc_closedir()
*/
#define SMBC_NOTIFY_CHANGE_FILE_NAME 0x001
#define SMBC_NOTIFY_CHANGE_DIR_NAME 0x002
#define SMBC_NOTIFY_CHANGE_ATTRIBUTES 0x004
#define SMBC_NOTIFY_CHANGE_SIZE 0x008
#define SMBC_NOTIFY_CHANGE_LAST_WRITE 0x010
#define SMBC_NOTIFY_CHANGE_LAST_ACCESS 0x020
#define SMBC_NOTIFY_CHANGE_CREATION 0x040
#define SMBC_NOTIFY_CHANGE_EA 0x080
#define SMBC_NOTIFY_CHANGE_SECURITY 0x100
#define SMBC_NOTIFY_CHANGE_STREAM_NAME 0x200
#define SMBC_NOTIFY_CHANGE_STREAM_SIZE 0x400
#define SMBC_NOTIFY_CHANGE_STREAM_WRITE 0x800
int smbc_notify(int dh, smbc_bool recursive, uint32_t completion_filter,
unsigned callback_timeout_ms,
smbc_notify_callback_fn cb, void *private_data);
/**@ingroup attribute
* Get information about a file or directory.

View File

@ -0,0 +1,179 @@
smbc_chmod: int (const char *, mode_t)
smbc_close: int (int)
smbc_closedir: int (int)
smbc_creat: int (const char *, mode_t)
smbc_fgetxattr: int (int, const char *, const void *, size_t)
smbc_flistxattr: int (int, char *, size_t)
smbc_free_context: int (SMBCCTX *, int)
smbc_fremovexattr: int (int, const char *)
smbc_fsetxattr: int (int, const char *, const void *, size_t, int)
smbc_fstat: int (int, struct stat *)
smbc_fstatvfs: int (int, struct statvfs *)
smbc_ftruncate: int (int, off_t)
smbc_getDebug: int (SMBCCTX *)
smbc_getFunctionAddCachedServer: smbc_add_cached_srv_fn (SMBCCTX *)
smbc_getFunctionAuthData: smbc_get_auth_data_fn (SMBCCTX *)
smbc_getFunctionAuthDataWithContext: smbc_get_auth_data_with_context_fn (SMBCCTX *)
smbc_getFunctionCheckServer: smbc_check_server_fn (SMBCCTX *)
smbc_getFunctionChmod: smbc_chmod_fn (SMBCCTX *)
smbc_getFunctionClose: smbc_close_fn (SMBCCTX *)
smbc_getFunctionClosedir: smbc_closedir_fn (SMBCCTX *)
smbc_getFunctionCreat: smbc_creat_fn (SMBCCTX *)
smbc_getFunctionFstat: smbc_fstat_fn (SMBCCTX *)
smbc_getFunctionFstatVFS: smbc_fstatvfs_fn (SMBCCTX *)
smbc_getFunctionFstatdir: smbc_fstatdir_fn (SMBCCTX *)
smbc_getFunctionFtruncate: smbc_ftruncate_fn (SMBCCTX *)
smbc_getFunctionGetCachedServer: smbc_get_cached_srv_fn (SMBCCTX *)
smbc_getFunctionGetdents: smbc_getdents_fn (SMBCCTX *)
smbc_getFunctionGetxattr: smbc_getxattr_fn (SMBCCTX *)
smbc_getFunctionListPrintJobs: smbc_list_print_jobs_fn (SMBCCTX *)
smbc_getFunctionListxattr: smbc_listxattr_fn (SMBCCTX *)
smbc_getFunctionLseek: smbc_lseek_fn (SMBCCTX *)
smbc_getFunctionLseekdir: smbc_lseekdir_fn (SMBCCTX *)
smbc_getFunctionMkdir: smbc_mkdir_fn (SMBCCTX *)
smbc_getFunctionNotify: smbc_notify_fn (SMBCCTX *)
smbc_getFunctionOpen: smbc_open_fn (SMBCCTX *)
smbc_getFunctionOpenPrintJob: smbc_open_print_job_fn (SMBCCTX *)
smbc_getFunctionOpendir: smbc_opendir_fn (SMBCCTX *)
smbc_getFunctionPrintFile: smbc_print_file_fn (SMBCCTX *)
smbc_getFunctionPurgeCachedServers: smbc_purge_cached_fn (SMBCCTX *)
smbc_getFunctionRead: smbc_read_fn (SMBCCTX *)
smbc_getFunctionReaddir: smbc_readdir_fn (SMBCCTX *)
smbc_getFunctionRemoveCachedServer: smbc_remove_cached_srv_fn (SMBCCTX *)
smbc_getFunctionRemoveUnusedServer: smbc_remove_unused_server_fn (SMBCCTX *)
smbc_getFunctionRemovexattr: smbc_removexattr_fn (SMBCCTX *)
smbc_getFunctionRename: smbc_rename_fn (SMBCCTX *)
smbc_getFunctionRmdir: smbc_rmdir_fn (SMBCCTX *)
smbc_getFunctionSetxattr: smbc_setxattr_fn (SMBCCTX *)
smbc_getFunctionSplice: smbc_splice_fn (SMBCCTX *)
smbc_getFunctionStat: smbc_stat_fn (SMBCCTX *)
smbc_getFunctionStatVFS: smbc_statvfs_fn (SMBCCTX *)
smbc_getFunctionTelldir: smbc_telldir_fn (SMBCCTX *)
smbc_getFunctionUnlink: smbc_unlink_fn (SMBCCTX *)
smbc_getFunctionUnlinkPrintJob: smbc_unlink_print_job_fn (SMBCCTX *)
smbc_getFunctionUtimes: smbc_utimes_fn (SMBCCTX *)
smbc_getFunctionWrite: smbc_write_fn (SMBCCTX *)
smbc_getNetbiosName: char *(SMBCCTX *)
smbc_getOptionBrowseMaxLmbCount: int (SMBCCTX *)
smbc_getOptionCaseSensitive: smbc_bool (SMBCCTX *)
smbc_getOptionDebugToStderr: smbc_bool (SMBCCTX *)
smbc_getOptionFallbackAfterKerberos: smbc_bool (SMBCCTX *)
smbc_getOptionFullTimeNames: smbc_bool (SMBCCTX *)
smbc_getOptionNoAutoAnonymousLogin: smbc_bool (SMBCCTX *)
smbc_getOptionOneSharePerServer: smbc_bool (SMBCCTX *)
smbc_getOptionOpenShareMode: smbc_share_mode (SMBCCTX *)
smbc_getOptionSmbEncryptionLevel: smbc_smb_encrypt_level (SMBCCTX *)
smbc_getOptionUrlEncodeReaddirEntries: smbc_bool (SMBCCTX *)
smbc_getOptionUseCCache: smbc_bool (SMBCCTX *)
smbc_getOptionUseKerberos: smbc_bool (SMBCCTX *)
smbc_getOptionUseNTHash: smbc_bool (SMBCCTX *)
smbc_getOptionUserData: void *(SMBCCTX *)
smbc_getPort: uint16_t (SMBCCTX *)
smbc_getServerCacheData: struct smbc_server_cache *(SMBCCTX *)
smbc_getTimeout: int (SMBCCTX *)
smbc_getUser: char *(SMBCCTX *)
smbc_getWorkgroup: char *(SMBCCTX *)
smbc_getdents: int (unsigned int, struct smbc_dirent *, int)
smbc_getxattr: int (const char *, const char *, const void *, size_t)
smbc_init: int (smbc_get_auth_data_fn, int)
smbc_init_context: SMBCCTX *(SMBCCTX *)
smbc_lgetxattr: int (const char *, const char *, const void *, size_t)
smbc_list_print_jobs: int (const char *, smbc_list_print_job_fn)
smbc_listxattr: int (const char *, char *, size_t)
smbc_llistxattr: int (const char *, char *, size_t)
smbc_lremovexattr: int (const char *, const char *)
smbc_lseek: off_t (int, off_t, int)
smbc_lseekdir: int (int, off_t)
smbc_lsetxattr: int (const char *, const char *, const void *, size_t, int)
smbc_mkdir: int (const char *, mode_t)
smbc_new_context: SMBCCTX *(void)
smbc_notify: int (int, smbc_bool, uint32_t, unsigned int, smbc_notify_callback_fn, void *)
smbc_open: int (const char *, int, mode_t)
smbc_open_print_job: int (const char *)
smbc_opendir: int (const char *)
smbc_option_get: void *(SMBCCTX *, char *)
smbc_option_set: void (SMBCCTX *, char *, ...)
smbc_print_file: int (const char *, const char *)
smbc_read: ssize_t (int, void *, size_t)
smbc_readdir: struct smbc_dirent *(unsigned int)
smbc_removexattr: int (const char *, const char *)
smbc_rename: int (const char *, const char *)
smbc_rmdir: int (const char *)
smbc_setDebug: void (SMBCCTX *, int)
smbc_setFunctionAddCachedServer: void (SMBCCTX *, smbc_add_cached_srv_fn)
smbc_setFunctionAuthData: void (SMBCCTX *, smbc_get_auth_data_fn)
smbc_setFunctionAuthDataWithContext: void (SMBCCTX *, smbc_get_auth_data_with_context_fn)
smbc_setFunctionCheckServer: void (SMBCCTX *, smbc_check_server_fn)
smbc_setFunctionChmod: void (SMBCCTX *, smbc_chmod_fn)
smbc_setFunctionClose: void (SMBCCTX *, smbc_close_fn)
smbc_setFunctionClosedir: void (SMBCCTX *, smbc_closedir_fn)
smbc_setFunctionCreat: void (SMBCCTX *, smbc_creat_fn)
smbc_setFunctionFstat: void (SMBCCTX *, smbc_fstat_fn)
smbc_setFunctionFstatVFS: void (SMBCCTX *, smbc_fstatvfs_fn)
smbc_setFunctionFstatdir: void (SMBCCTX *, smbc_fstatdir_fn)
smbc_setFunctionFtruncate: void (SMBCCTX *, smbc_ftruncate_fn)
smbc_setFunctionGetCachedServer: void (SMBCCTX *, smbc_get_cached_srv_fn)
smbc_setFunctionGetdents: void (SMBCCTX *, smbc_getdents_fn)
smbc_setFunctionGetxattr: void (SMBCCTX *, smbc_getxattr_fn)
smbc_setFunctionListPrintJobs: void (SMBCCTX *, smbc_list_print_jobs_fn)
smbc_setFunctionListxattr: void (SMBCCTX *, smbc_listxattr_fn)
smbc_setFunctionLseek: void (SMBCCTX *, smbc_lseek_fn)
smbc_setFunctionLseekdir: void (SMBCCTX *, smbc_lseekdir_fn)
smbc_setFunctionMkdir: void (SMBCCTX *, smbc_mkdir_fn)
smbc_setFunctionNotify: void (SMBCCTX *, smbc_notify_fn)
smbc_setFunctionOpen: void (SMBCCTX *, smbc_open_fn)
smbc_setFunctionOpenPrintJob: void (SMBCCTX *, smbc_open_print_job_fn)
smbc_setFunctionOpendir: void (SMBCCTX *, smbc_opendir_fn)
smbc_setFunctionPrintFile: void (SMBCCTX *, smbc_print_file_fn)
smbc_setFunctionPurgeCachedServers: void (SMBCCTX *, smbc_purge_cached_fn)
smbc_setFunctionRead: void (SMBCCTX *, smbc_read_fn)
smbc_setFunctionReaddir: void (SMBCCTX *, smbc_readdir_fn)
smbc_setFunctionRemoveCachedServer: void (SMBCCTX *, smbc_remove_cached_srv_fn)
smbc_setFunctionRemoveUnusedServer: void (SMBCCTX *, smbc_remove_unused_server_fn)
smbc_setFunctionRemovexattr: void (SMBCCTX *, smbc_removexattr_fn)
smbc_setFunctionRename: void (SMBCCTX *, smbc_rename_fn)
smbc_setFunctionRmdir: void (SMBCCTX *, smbc_rmdir_fn)
smbc_setFunctionSetxattr: void (SMBCCTX *, smbc_setxattr_fn)
smbc_setFunctionSplice: void (SMBCCTX *, smbc_splice_fn)
smbc_setFunctionStat: void (SMBCCTX *, smbc_stat_fn)
smbc_setFunctionStatVFS: void (SMBCCTX *, smbc_statvfs_fn)
smbc_setFunctionTelldir: void (SMBCCTX *, smbc_telldir_fn)
smbc_setFunctionUnlink: void (SMBCCTX *, smbc_unlink_fn)
smbc_setFunctionUnlinkPrintJob: void (SMBCCTX *, smbc_unlink_print_job_fn)
smbc_setFunctionUtimes: void (SMBCCTX *, smbc_utimes_fn)
smbc_setFunctionWrite: void (SMBCCTX *, smbc_write_fn)
smbc_setNetbiosName: void (SMBCCTX *, char *)
smbc_setOptionBrowseMaxLmbCount: void (SMBCCTX *, int)
smbc_setOptionCaseSensitive: void (SMBCCTX *, smbc_bool)
smbc_setOptionDebugToStderr: void (SMBCCTX *, smbc_bool)
smbc_setOptionFallbackAfterKerberos: void (SMBCCTX *, smbc_bool)
smbc_setOptionFullTimeNames: void (SMBCCTX *, smbc_bool)
smbc_setOptionNoAutoAnonymousLogin: void (SMBCCTX *, smbc_bool)
smbc_setOptionOneSharePerServer: void (SMBCCTX *, smbc_bool)
smbc_setOptionOpenShareMode: void (SMBCCTX *, smbc_share_mode)
smbc_setOptionSmbEncryptionLevel: void (SMBCCTX *, smbc_smb_encrypt_level)
smbc_setOptionUrlEncodeReaddirEntries: void (SMBCCTX *, smbc_bool)
smbc_setOptionUseCCache: void (SMBCCTX *, smbc_bool)
smbc_setOptionUseKerberos: void (SMBCCTX *, smbc_bool)
smbc_setOptionUseNTHash: void (SMBCCTX *, smbc_bool)
smbc_setOptionUserData: void (SMBCCTX *, void *)
smbc_setPort: void (SMBCCTX *, uint16_t)
smbc_setServerCacheData: void (SMBCCTX *, struct smbc_server_cache *)
smbc_setTimeout: void (SMBCCTX *, int)
smbc_setUser: void (SMBCCTX *, char *)
smbc_setWorkgroup: void (SMBCCTX *, char *)
smbc_set_context: SMBCCTX *(SMBCCTX *)
smbc_set_credentials: void (const char *, const char *, const char *, smbc_bool, const char *)
smbc_set_credentials_with_fallback: void (SMBCCTX *, const char *, const char *, const char *)
smbc_setxattr: int (const char *, const char *, const void *, size_t, int)
smbc_stat: int (const char *, struct stat *)
smbc_statvfs: int (char *, struct statvfs *)
smbc_telldir: off_t (int)
smbc_unlink: int (const char *)
smbc_unlink_print_job: int (const char *, int)
smbc_urldecode: int (char *, char *, size_t)
smbc_urlencode: int (char *, char *, int)
smbc_utime: int (const char *, struct utimbuf *)
smbc_utimes: int (const char *, struct timeval *)
smbc_version: const char *(void)
smbc_write: ssize_t (int, const void *, size_t)

View File

@ -313,6 +313,17 @@ smbc_rmdir(const char *durl)
return smbc_getFunctionRmdir(statcont)(statcont, durl);
}
int
smbc_notify(int dh, smbc_bool recursive, uint32_t completion_filter,
unsigned callback_timeout_ms,
smbc_notify_callback_fn cb, void *private_data)
{
SMBCFILE *dir = find_fd(dh);
return smbc_getFunctionNotify(statcont)(
statcont, dir, recursive, completion_filter,
callback_timeout_ms, cb, private_data);
}
int
smbc_stat(const char *url,
struct stat *st)

View File

@ -214,6 +214,7 @@ smbc_new_context(void)
smbc_setFunctionTelldir(context, SMBC_telldir_ctx);
smbc_setFunctionLseekdir(context, SMBC_lseekdir_ctx);
smbc_setFunctionFstatdir(context, SMBC_fstatdir_ctx);
smbc_setFunctionNotify(context, SMBC_notify_ctx);
smbc_setFunctionChmod(context, SMBC_chmod_ctx);
smbc_setFunctionUtimes(context, SMBC_utimes_ctx);
smbc_setFunctionSetxattr(context, SMBC_setxattr_ctx);

View File

@ -31,6 +31,8 @@
#include "../librpc/gen_ndr/ndr_srvsvc_c.h"
#include "libsmb/nmblib.h"
#include "../libcli/smb/smbXcli_base.h"
#include "../libcli/security/security.h"
#include "lib/util/tevent_ntstatus.h"
/*
* Routine to open a directory
@ -2047,3 +2049,255 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
return 0; /* Success */
}
struct smbc_notify_cb_state {
struct tevent_context *ev;
struct cli_state *cli;
uint16_t fnum;
bool recursive;
uint32_t completion_filter;
unsigned callback_timeout_ms;
smbc_notify_callback_fn cb;
void *private_data;
};
static void smbc_notify_cb_got_changes(struct tevent_req *subreq);
static void smbc_notify_cb_timedout(struct tevent_req *subreq);
static struct tevent_req *smbc_notify_cb_send(
TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
uint16_t fnum, bool recursive, uint32_t completion_filter,
unsigned callback_timeout_ms,
smbc_notify_callback_fn cb, void *private_data)
{
struct tevent_req *req, *subreq;
struct smbc_notify_cb_state *state;
req = tevent_req_create(mem_ctx, &state, struct smbc_notify_cb_state);
if (req == NULL) {
return NULL;
}
state->ev = ev;
state->cli = cli;
state->fnum = fnum;
state->recursive = recursive;
state->completion_filter = completion_filter;
state->callback_timeout_ms = callback_timeout_ms;
state->cb = cb;
state->private_data = private_data;
subreq = cli_notify_send(
state, state->ev, state->cli, state->fnum, 1000,
state->completion_filter, state->recursive);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
tevent_req_set_callback(subreq, smbc_notify_cb_got_changes, req);
if (state->callback_timeout_ms == 0) {
return req;
}
subreq = tevent_wakeup_send(
state, state->ev,
tevent_timeval_current_ofs(state->callback_timeout_ms/1000,
state->callback_timeout_ms*1000));
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
tevent_req_set_callback(subreq, smbc_notify_cb_timedout, req);
return req;
}
static void smbc_notify_cb_got_changes(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
struct smbc_notify_cb_state *state = tevent_req_data(
req, struct smbc_notify_cb_state);
uint32_t num_changes;
struct notify_change *changes;
NTSTATUS status;
int cb_ret;
status = cli_notify_recv(subreq, state, &num_changes, &changes);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
}
{
struct smbc_notify_callback_action actions[num_changes];
uint32_t i;
for (i=0; i<num_changes; i++) {
actions[i].action = changes[i].action;
actions[i].filename = changes[i].name;
}
cb_ret = state->cb(actions, num_changes, state->private_data);
}
TALLOC_FREE(changes);
if (cb_ret != 0) {
tevent_req_done(req);
return;
}
subreq = cli_notify_send(
state, state->ev, state->cli, state->fnum, 1000,
state->completion_filter, state->recursive);
if (tevent_req_nomem(subreq, req)) {
return;
}
tevent_req_set_callback(subreq, smbc_notify_cb_got_changes, req);
}
static void smbc_notify_cb_timedout(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
struct smbc_notify_cb_state *state = tevent_req_data(
req, struct smbc_notify_cb_state);
int cb_ret;
bool ok;
ok = tevent_wakeup_recv(subreq);
TALLOC_FREE(subreq);
if (!ok) {
tevent_req_oom(req);
return;
}
cb_ret = state->cb(NULL, 0, state->private_data);
if (cb_ret != 0) {
tevent_req_done(req);
return;
}
subreq = tevent_wakeup_send(
state, state->ev,
tevent_timeval_current_ofs(state->callback_timeout_ms/1000,
state->callback_timeout_ms*1000));
if (tevent_req_nomem(subreq, req)) {
return;
}
tevent_req_set_callback(subreq, smbc_notify_cb_timedout, req);
}
static NTSTATUS smbc_notify_cb_recv(struct tevent_req *req)
{
return tevent_req_simple_recv_ntstatus(req);
}
static NTSTATUS smbc_notify_cb(struct cli_state *cli, uint16_t fnum,
bool recursive, uint32_t completion_filter,
unsigned callback_timeout_ms,
smbc_notify_callback_fn cb, void *private_data)
{
TALLOC_CTX *frame = talloc_stackframe();
struct tevent_context *ev;
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
ev = samba_tevent_context_init(frame);
if (ev == NULL) {
goto fail;
}
req = smbc_notify_cb_send(frame, ev, cli, fnum, recursive,
completion_filter,
callback_timeout_ms, cb, private_data);
if (req == NULL) {
goto fail;
}
if (!tevent_req_poll_ntstatus(req, ev, &status)) {
goto fail;
}
status = smbc_notify_cb_recv(req);
TALLOC_FREE(req);
fail:
TALLOC_FREE(frame);
return status;
}
int
SMBC_notify_ctx(SMBCCTX *context, SMBCFILE *dir, smbc_bool recursive,
uint32_t completion_filter, unsigned callback_timeout_ms,
smbc_notify_callback_fn cb, void *private_data)
{
TALLOC_CTX *frame = talloc_stackframe();
struct cli_state *cli = dir->srv->cli;
char *server = NULL;
char *share = NULL;
char *user = NULL;
char *password = NULL;
char *options = NULL;
char *workgroup = NULL;
char *path = NULL;
uint16_t port;
NTSTATUS status;
uint16_t fnum;
if ((context == NULL) || !context->internal->initialized) {
TALLOC_FREE(frame);
errno = EINVAL;
return -1;
}
if ((dir == NULL) ||
!SMBC_dlist_contains(context->internal->files, dir)) {
TALLOC_FREE(frame);
errno = EBADF;
return -1;
}
if (SMBC_parse_path(frame,
context,
dir->fname,
&workgroup,
&server,
&port,
&share,
&path,
&user,
&password,
&options)) {
DEBUG(4, ("no valid path\n"));
TALLOC_FREE(frame);
errno = EINVAL + 8194;
return -1;
}
DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' "
"path='%s' options='%s'\n",
dir->fname, server, share, path, options));
DEBUG(4, ("%s(%p, %d, %"PRIu32")\n", __func__, dir,
(int)recursive, completion_filter));
status = cli_ntcreate(
cli, path, 0, FILE_READ_DATA, 0,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN, 0, 0, &fnum, NULL);
if (!NT_STATUS_IS_OK(status)) {
int err = SMBC_errno(context, cli);
TALLOC_FREE(frame);
errno = err;
return -1;
}
status = smbc_notify_cb(cli, fnum, recursive != 0, completion_filter,
callback_timeout_ms, cb, private_data);
if (!NT_STATUS_IS_OK(status)) {
int err = SMBC_errno(context, cli);
cli_close(cli, fnum);
TALLOC_FREE(frame);
errno = err;
return -1;
}
cli_close(cli, fnum);
TALLOC_FREE(frame);
return 0;
}

View File

@ -928,6 +928,18 @@ smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn)
c->fstatdir = fn;
}
smbc_notify_fn
smbc_getFunctionNotify(SMBCCTX *c)
{
return c->internal->smb.notify_fn;
}
void
smbc_setFunctionNotify(SMBCCTX *c, smbc_notify_fn fn)
{
c->internal->smb.notify_fn = fn;
}
/**
* Callable functions applicable to both files and directories.

View File

@ -27,5 +27,5 @@ def build(bld):
public_headers='../include/libsmbclient.h',
abi_directory='ABI',
abi_match='smbc_*',
vnum='0.2.2',
vnum='0.2.3',
pc_files='smbclient.pc')