2 Unix SMB/Netbios implementation.
3 SMB client library implementation
4 Copyright (C) Andrew Tridgell 1998
5 Copyright (C) Richard Sharpe 2000, 2002
6 Copyright (C) John Terpstra 2000
7 Copyright (C) Tom Jansen (Ninja ISD) 2002
8 Copyright (C) Derrell Lipman 2003-2008
9 Copyright (C) Jeremy Allison 2007, 2008
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "libsmbclient.h"
27 #include "libsmb_internal.h"
31 * Is the logging working / configfile read ?
33 static int SMBC_initialized = 0;
38 * Get a new empty handle to fill in with your own info
41 smbc_new_context(void)
45 context = SMB_MALLOC_P(SMBCCTX);
52 /* Initialize the context and establish reasonable defaults */
53 ZERO_STRUCTP(context);
56 context->timeout = 20000; /* 20 seconds */
58 context->full_time_names = False;
59 context->share_mode = SMBC_SHAREMODE_DENY_NONE;
60 context->smb_encryption_level = 0;
61 context->browse_max_lmb_count = 3; /* # LMBs to query */
62 context->urlencode_readdir_entries = False;
63 context->one_share_per_server = False;
64 context->use_kerberos = False;
65 context->fallback_after_kerberos = False;
66 context->no_auto_anonymous_login = False;
68 context->server.get_auth_data_fn = SMBC_get_auth_data;
69 context->server.check_server_fn = SMBC_check_server;
70 context->server.remove_unused_server_fn = SMBC_remove_unused_server;
72 context->cache.server_cache_data = NULL;
73 context->cache.add_cached_server_fn = SMBC_add_cached_server;
74 context->cache.get_cached_server_fn = SMBC_get_cached_server;
75 context->cache.remove_cached_server_fn = SMBC_remove_cached_server;
76 context->cache.purge_cached_server_fn = SMBC_purge_cached_servers;
78 context->posix_emu.open_fn = SMBC_open_ctx;
79 context->posix_emu.creat_fn = SMBC_creat_ctx;
80 context->posix_emu.read_fn = SMBC_read_ctx;
81 context->posix_emu.write_fn = SMBC_write_ctx;
82 context->posix_emu.close_fn = SMBC_close_ctx;
83 context->posix_emu.unlink_fn = SMBC_unlink_ctx;
84 context->posix_emu.rename_fn = SMBC_rename_ctx;
85 context->posix_emu.lseek_fn = SMBC_lseek_ctx;
86 context->posix_emu.ftruncate_fn = SMBC_ftruncate_ctx;
87 context->posix_emu.stat_fn = SMBC_stat_ctx;
88 context->posix_emu.fstat_fn = SMBC_fstat_ctx;
89 context->posix_emu.opendir_fn = SMBC_opendir_ctx;
90 context->posix_emu.closedir_fn = SMBC_closedir_ctx;
91 context->posix_emu.readdir_fn = SMBC_readdir_ctx;
92 context->posix_emu.getdents_fn = SMBC_getdents_ctx;
93 context->posix_emu.mkdir_fn = SMBC_mkdir_ctx;
94 context->posix_emu.rmdir_fn = SMBC_rmdir_ctx;
95 context->posix_emu.telldir_fn = SMBC_telldir_ctx;
96 context->posix_emu.lseekdir_fn = SMBC_lseekdir_ctx;
97 context->posix_emu.fstatdir_fn = SMBC_fstatdir_ctx;
98 context->posix_emu.chmod_fn = SMBC_chmod_ctx;
99 context->posix_emu.utimes_fn = SMBC_utimes_ctx;
100 context->posix_emu.setxattr_fn = SMBC_setxattr_ctx;
101 context->posix_emu.getxattr_fn = SMBC_getxattr_ctx;
102 context->posix_emu.removexattr_fn = SMBC_removexattr_ctx;
103 context->posix_emu.listxattr_fn = SMBC_listxattr_ctx;
105 context->printing.open_print_job_fn = SMBC_open_print_job_ctx;
106 context->printing.print_file_fn = SMBC_print_file_ctx;
107 context->printing.list_print_jobs_fn = SMBC_list_print_jobs_ctx;
108 context->printing.unlink_print_job_fn = SMBC_unlink_print_job_ctx;
116 * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed
117 * and thus you'll be leaking memory if not handled properly.
121 smbc_free_context(SMBCCTX *context,
131 DEBUG(1,("Performing aggressive shutdown.\n"));
135 (context->posix_emu.close_fn)(context, f);
138 context->files = NULL;
140 /* First try to remove the servers the nice way. */
141 if (context->cache.purge_cached_server_fn(context)) {
144 DEBUG(1, ("Could not purge all servers, "
145 "Nice way shutdown failed.\n"));
146 s = context->servers;
148 DEBUG(1, ("Forced shutdown: %p (fd=%d)\n",
150 cli_shutdown(s->cli);
151 (context->cache.remove_cached_server_fn)(context,
154 DLIST_REMOVE(context->servers, s);
158 context->servers = NULL;
162 /* This is the polite way */
163 if ((context->cache.purge_cached_server_fn)(context)) {
164 DEBUG(1, ("Could not purge all servers, "
165 "free_context failed.\n"));
169 if (context->servers) {
170 DEBUG(1, ("Active servers in context, "
171 "free_context failed.\n"));
175 if (context->files) {
176 DEBUG(1, ("Active files in context, "
177 "free_context failed.\n"));
183 /* Things we have to clean up */
184 SAFE_FREE(context->workgroup);
185 SAFE_FREE(context->netbios_name);
186 SAFE_FREE(context->user);
188 DEBUG(3, ("Context %p successfully freed\n", context));
195 * Each time the context structure is changed, we have binary backward
196 * compatibility issues. Instead of modifying the public portions of the
197 * context structure to add new options, instead, we put them in the internal
198 * portion of the context structure and provide a set function for these new
202 smbc_option_set(SMBCCTX *context,
204 ... /* option_value */)
210 smbc_get_auth_data_with_context_fn auth_fn;
215 va_start(ap, option_name);
217 if (strcmp(option_name, "debug_to_stderr") == 0) {
219 * Log to standard error instead of standard output.
221 option_value.b = (bool) va_arg(ap, int);
222 context->debug_stderr = option_value.b;
224 } else if (strcmp(option_name, "full_time_names") == 0) {
226 * Use new-style time attribute names, e.g. WRITE_TIME rather
227 * than the old-style names such as M_TIME. This allows also
228 * setting/getting CREATE_TIME which was previously
229 * unimplemented. (Note that the old C_TIME was supposed to
230 * be CHANGE_TIME but was confused and sometimes referred to
233 option_value.b = (bool) va_arg(ap, int);
234 context->full_time_names = option_value.b;
236 } else if (strcmp(option_name, "open_share_mode") == 0) {
238 * The share mode to use for files opened with
239 * SMBC_open_ctx(). The default is SMBC_SHAREMODE_DENY_NONE.
241 option_value.i = va_arg(ap, int);
242 context->share_mode = (smbc_share_mode) option_value.i;
244 } else if (strcmp(option_name, "user_data") == 0) {
246 * Save a user data handle which may be retrieved by the user
247 * with smbc_option_get()
249 option_value.v = va_arg(ap, void *);
250 context->user_data = option_value.v;
251 } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
253 * Save an encoded value for encryption level.
254 * 0 = off, 1 = attempt, 2 = required.
256 option_value.s = va_arg(ap, const char *);
257 if (strcmp(option_value.s, "none") == 0) {
258 context->smb_encryption_level = 0;
259 } else if (strcmp(option_value.s, "request") == 0) {
260 context->smb_encryption_level = 1;
261 } else if (strcmp(option_value.s, "require") == 0) {
262 context->smb_encryption_level = 2;
264 } else if (strcmp(option_name, "browse_max_lmb_count") == 0) {
266 * From how many local master browsers should the list of
267 * workgroups be retrieved? It can take up to 12 minutes or
268 * longer after a server becomes a local master browser, for
269 * it to have the entire browse list (the list of
270 * workgroups/domains) from an entire network. Since a client
271 * never knows which local master browser will be found first,
272 * the one which is found first and used to retrieve a browse
273 * list may have an incomplete or empty browse list. By
274 * requesting the browse list from multiple local master
275 * browsers, a more complete list can be generated. For small
276 * networks (few workgroups), it is recommended that this
277 * value be set to 0, causing the browse lists from all found
278 * local master browsers to be retrieved and merged. For
279 * networks with many workgroups, a suitable value for this
280 * variable is probably somewhere around 3. (Default: 3).
282 option_value.i = va_arg(ap, int);
283 context->browse_max_lmb_count = option_value.i;
285 } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) {
287 * There is a difference in the desired return strings from
288 * smbc_readdir() depending upon whether the filenames are to
289 * be displayed to the user, or whether they are to be
290 * appended to the path name passed to smbc_opendir() to call
291 * a further smbc_ function (e.g. open the file with
292 * smbc_open()). In the former case, the filename should be
293 * in "human readable" form. In the latter case, the smbc_
294 * functions expect a URL which must be url-encoded. Those
295 * functions decode the URL. If, for example, smbc_readdir()
296 * returned a file name of "abc%20def.txt", passing a path
297 * with this file name attached to smbc_open() would cause
298 * smbc_open to attempt to open the file "abc def.txt" since
299 * the %20 is decoded into a space.
301 * Set this option to True if the names returned by
302 * smbc_readdir() should be url-encoded such that they can be
303 * passed back to another smbc_ call. Set it to False if the
304 * names returned by smbc_readdir() are to be presented to the
307 * For backwards compatibility, this option defaults to False.
309 option_value.b = (bool) va_arg(ap, int);
310 context->urlencode_readdir_entries = option_value.b;
312 } else if (strcmp(option_name, "one_share_per_server") == 0) {
314 * Some Windows versions appear to have a limit to the number
315 * of concurrent SESSIONs and/or TREE CONNECTions. In
316 * one-shot programs (i.e. the program runs and then quickly
317 * ends, thereby shutting down all connections), it is
318 * probably reasonable to establish a new connection for each
319 * share. In long-running applications, the limitation can be
320 * avoided by using only a single connection to each server,
321 * and issuing a new TREE CONNECT when the share is accessed.
323 option_value.b = (bool) va_arg(ap, int);
324 context->one_share_per_server = option_value.b;
326 } else if (strcmp(option_name, "use_kerberos") == 0) {
327 option_value.b = (bool) va_arg(ap, int);
328 context->use_kerberos = option_value.b;
330 } else if (strcmp(option_name, "fallback_after_kerberos") == 0) {
331 option_value.b = (bool) va_arg(ap, int);
332 context->fallback_after_kerberos = option_value.b;
334 } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) {
335 option_value.b = (bool) va_arg(ap, int);
336 context->no_auto_anonymous_login = option_value.b;
344 * Retrieve the current value of an option
347 smbc_option_get(SMBCCTX *context,
350 if (strcmp(option_name, "debug_stderr") == 0) {
352 * Log to standard error instead of standard output.
354 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
355 return (void *) (intptr_t) context->debug_stderr;
357 return (void *) context->debug_stderr;
360 } else if (strcmp(option_name, "full_time_names") == 0) {
362 * Use new-style time attribute names, e.g. WRITE_TIME rather
363 * than the old-style names such as M_TIME. This allows also
364 * setting/getting CREATE_TIME which was previously
365 * unimplemented. (Note that the old C_TIME was supposed to
366 * be CHANGE_TIME but was confused and sometimes referred to
369 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
370 return (void *) (intptr_t) context->full_time_names;
372 return (void *) context->full_time_names;
375 } else if (strcmp(option_name, "user_data") == 0) {
377 * Return the user data handle which was saved by the user
378 * with smbc_option_set()
380 return context->user_data;
382 } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
384 * Return the current smb encrypt negotiate option as a string.
386 switch (context->smb_encryption_level) {
388 return (void *) "none";
390 return (void *) "request";
392 return (void *) "require";
395 } else if (strcmp(option_name, "smb_encrypt_on") == 0) {
397 * Return the current smb encrypt status option as a bool.
398 * false = off, true = on. We don't know what server is
399 * being requested, so we only return true if all servers
400 * are using an encrypted connection.
403 unsigned int num_servers = 0;
405 for (s = context->servers; s; s = s->next) {
407 if (s->cli->trans_enc_state == NULL) {
408 return (void *)false;
411 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
412 return (void *) (intptr_t) (bool) (num_servers > 0);
414 return (void *) (bool) (num_servers > 0);
417 } else if (strcmp(option_name, "browse_max_lmb_count") == 0) {
419 * From how many local master browsers should the list of
420 * workgroups be retrieved? It can take up to 12 minutes or
421 * longer after a server becomes a local master browser, for
422 * it to have the entire browse list (the list of
423 * workgroups/domains) from an entire network. Since a client
424 * never knows which local master browser will be found first,
425 * the one which is found first and used to retrieve a browse
426 * list may have an incomplete or empty browse list. By
427 * requesting the browse list from multiple local master
428 * browsers, a more complete list can be generated. For small
429 * networks (few workgroups), it is recommended that this
430 * value be set to 0, causing the browse lists from all found
431 * local master browsers to be retrieved and merged. For
432 * networks with many workgroups, a suitable value for this
433 * variable is probably somewhere around 3. (Default: 3).
435 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
436 return (void *) (intptr_t) context->browse_max_lmb_count;
438 return (void *) context->browse_max_lmb_count;
441 } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) {
443 * There is a difference in the desired return strings from
444 * smbc_readdir() depending upon whether the filenames are to
445 * be displayed to the user, or whether they are to be
446 * appended to the path name passed to smbc_opendir() to call
447 * a further smbc_ function (e.g. open the file with
448 * smbc_open()). In the former case, the filename should be
449 * in "human readable" form. In the latter case, the smbc_
450 * functions expect a URL which must be url-encoded. Those
451 * functions decode the URL. If, for example, smbc_readdir()
452 * returned a file name of "abc%20def.txt", passing a path
453 * with this file name attached to smbc_open() would cause
454 * smbc_open to attempt to open the file "abc def.txt" since
455 * the %20 is decoded into a space.
457 * Set this option to True if the names returned by
458 * smbc_readdir() should be url-encoded such that they can be
459 * passed back to another smbc_ call. Set it to False if the
460 * names returned by smbc_readdir() are to be presented to the
463 * For backwards compatibility, this option defaults to False.
465 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
466 return (void *) (intptr_t) context->urlencode_readdir_entries;
468 return (void *) (bool) context->urlencode_readdir_entries;
471 } else if (strcmp(option_name, "one_share_per_server") == 0) {
473 * Some Windows versions appear to have a limit to the number
474 * of concurrent SESSIONs and/or TREE CONNECTions. In
475 * one-shot programs (i.e. the program runs and then quickly
476 * ends, thereby shutting down all connections), it is
477 * probably reasonable to establish a new connection for each
478 * share. In long-running applications, the limitation can be
479 * avoided by using only a single connection to each server,
480 * and issuing a new TREE CONNECT when the share is accessed.
482 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
483 return (void *) (intptr_t) context->one_share_per_server;
485 return (void *) (bool) context->one_share_per_server;
488 } else if (strcmp(option_name, "use_kerberos") == 0) {
489 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
490 return (void *) (intptr_t) context->use_kerberos;
492 return (void *) (bool) context->use_kerberos;
495 } else if (strcmp(option_name, "fallback_after_kerberos") == 0) {
496 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
497 return (void *) (intptr_t) context->fallback_after_kerberos;
499 return (void *) (bool) context->fallback_after_kerberos;
502 } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) {
503 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
504 return (void *) (intptr_t) context->no_auto_anonymous_login;
506 return (void *) (bool) context->no_auto_anonymous_login;
515 * Initialize the library, etc.
517 * We accept a struct containing handle information.
518 * valid values for info->debug from 0 to 100,
519 * and insist that info->fn must be non-null.
522 smbc_init_context(SMBCCTX *context)
527 extern bool in_client;
534 /* Do not initialise the same client twice */
535 if (context->initialized) {
539 if (!context->server.get_auth_data_fn ||
540 context->debug < 0 ||
541 context->debug > 100) {
548 if (!SMBC_initialized) {
550 * Do some library-wide intializations the first time we get
553 bool conf_loaded = False;
554 TALLOC_CTX *frame = talloc_stackframe();
556 /* Set this to what the user wants */
557 DEBUGLEVEL = context->debug;
561 setup_logging("libsmbclient", True);
562 if (context->debug_stderr) {
564 x_setbuf(x_stderr, NULL);
567 /* Here we would open the smb.conf file if needed ... */
569 in_client = True; /* FIXME, make a param */
571 home = getenv("HOME");
574 if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) {
575 if (lp_load(conf, True, False, False, True)) {
578 DEBUG(5, ("Could not load config file: %s\n",
587 * Well, if that failed, try the get_dyn_CONFIGFILE
588 * Which points to the standard locn, and if that
589 * fails, silently ignore it and use the internal
593 if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) {
594 DEBUG(5, ("Could not load config file: %s\n",
595 get_dyn_CONFIGFILE()));
599 * We loaded the global config file. Now lets
600 * load user-specific modifications to the
604 "%s/.smb/smb.conf.append",
606 if (!lp_load(conf, True, False, False, False)) {
608 ("Could not append config file: "
617 load_interfaces(); /* Load the list of interfaces ... */
619 reopen_logs(); /* Get logging working ... */
622 * Block SIGPIPE (from lib/util_sock.c: write())
623 * It is not needed and should not stop execution
625 BlockSignals(True, SIGPIPE);
627 /* Done with one-time initialisation */
628 SMBC_initialized = 1;
633 if (!context->user) {
635 * FIXME: Is this the best way to get the user info?
637 user = getenv("USER");
638 /* walk around as "guest" if no username can be found */
639 if (!user) context->user = SMB_STRDUP("guest");
640 else context->user = SMB_STRDUP(user);
643 if (!context->netbios_name) {
645 * We try to get our netbios name from the config. If that
646 * fails we fall back on constructing our netbios name from
649 if (global_myname()) {
650 context->netbios_name = SMB_STRDUP(global_myname());
654 * Hmmm, I want to get hostname as well, but I am too
655 * lazy for the moment
658 context->netbios_name = (char *)SMB_MALLOC(17);
659 if (!context->netbios_name) {
663 slprintf(context->netbios_name, 16,
664 "smbc%s%d", context->user, pid);
668 DEBUG(1, ("Using netbios name %s.\n", context->netbios_name));
670 if (!context->workgroup) {
671 if (lp_workgroup()) {
672 context->workgroup = SMB_STRDUP(lp_workgroup());
675 /* TODO: Think about a decent default workgroup */
676 context->workgroup = SMB_STRDUP("samba");
680 DEBUG(1, ("Using workgroup %s.\n", context->workgroup));
682 /* shortest timeout is 1 second */
683 if (context->timeout > 0 && context->timeout < 1000)
684 context->timeout = 1000;
687 * FIXME: Should we check the function pointers here?
690 context->initialized = True;
696 /* Return the verion of samba, and thus libsmbclient */
700 return samba_version_string();
704 /** Get the netbios name used for making connections */
706 smbc_getNetbiosName(SMBCCTX *c)
708 return c->netbios_name;
711 /** Set the netbios name used for making connections */
713 smbc_setNetbiosName(SMBCCTX *c, char * netbios_name)
715 c->netbios_name = netbios_name;
718 /** Get the workgroup used for making connections */
720 smbc_getWorkgroup(SMBCCTX *c)
725 /** Set the workgroup used for making connections */
727 smbc_setWorkgroup(SMBCCTX *c, char * workgroup)
729 c->workgroup = workgroup;
732 /** Get the username used for making connections */
734 smbc_getUser(SMBCCTX *c)
739 /** Set the username used for making connections */
741 smbc_setUser(SMBCCTX *c, char * user)
746 /** Get the debug level */
748 smbc_getDebug(SMBCCTX *c)
753 /** Set the debug level */
755 smbc_setDebug(SMBCCTX *c, int debug)
761 * Get the timeout used for waiting on connections and response data
765 smbc_getTimeout(SMBCCTX *c)
771 * Set the timeout used for waiting on connections and response data
775 smbc_setTimeout(SMBCCTX *c, int timeout)
777 c->timeout = timeout;
780 /** Get the function for obtaining authentication data */
782 smbc_get_auth_data_fn
783 smbc_getFunctionAuthData(SMBCCTX *c)
785 return c->server.get_auth_data_fn;
788 /** Set the function for obtaining authentication data */
790 smbc_setFunctionAuthData(SMBCCTX *c, smbc_get_auth_data_fn fn)
792 c->server.get_auth_data_fn = fn;
795 /** Get the function for checking if a server is still good */
797 smbc_getFunctionCheckServer(SMBCCTX *c)
799 return c->server.check_server_fn;
802 /** Set the function for checking if a server is still good */
804 smbc_setFunctionCheckServer(SMBCCTX *c, smbc_check_server_fn fn)
806 c->server.check_server_fn = fn;
809 /** Get the function for removing a server if unused */
810 smbc_remove_unused_server_fn
811 smbc_getFunctionRemoveUnusedServer(SMBCCTX *c)
813 return c->server.remove_unused_server_fn;
816 /** Set the function for removing a server if unused */
818 smbc_setFunctionRemoveUnusedServer(SMBCCTX *c,
819 smbc_remove_unused_server_fn fn)
821 c->server.remove_unused_server_fn = fn;
824 /** Get the function to store private data of the server cache */
826 smbc_server_cache * smbc_getServerCacheData(SMBCCTX *c)
828 return c->cache.server_cache_data;
831 /** Set the function to store private data of the server cache */
833 smbc_setServerCacheData(SMBCCTX *c, struct smbc_server_cache * cache)
835 c->cache.server_cache_data = cache;
839 /** Get the function for adding a cached server */
840 smbc_add_cached_srv_fn
841 smbc_getFunctionAddCachedServer(SMBCCTX *c)
843 return c->cache.add_cached_server_fn;
846 /** Set the function for adding a cached server */
848 smbc_setFunctionAddCachedServer(SMBCCTX *c, smbc_add_cached_srv_fn fn)
850 c->cache.add_cached_server_fn = fn;
853 /** Get the function for server cache lookup */
854 smbc_get_cached_srv_fn
855 smbc_getFunctionGetCachedServer(SMBCCTX *c)
857 return c->cache.get_cached_server_fn;
860 /** Set the function for server cache lookup */
862 smbc_setFunctionGetCachedServer(SMBCCTX *c, smbc_get_cached_srv_fn fn)
864 c->cache.get_cached_server_fn = fn;
867 /** Get the function for server cache removal */
868 smbc_remove_cached_srv_fn
869 smbc_getFunctionRemoveCachedServer(SMBCCTX *c)
871 return c->cache.remove_cached_server_fn;
874 /** Set the function for server cache removal */
876 smbc_setFunctionRemoveCachedServer(SMBCCTX *c,
877 smbc_remove_cached_srv_fn fn)
879 c->cache.remove_cached_server_fn = fn;
883 * Get the function for server cache purging. This function tries to
884 * remove all cached servers (e.g. on disconnect)
886 smbc_purge_cached_srv_fn
887 smbc_getFunctionPurgeCachedServers(SMBCCTX *c)
889 return c->cache.purge_cached_server_fn;
893 * Set the function for server cache purging. This function tries to
894 * remove all cached servers (e.g. on disconnect)
897 smbc_setFunctionPurgeCachedServers(SMBCCTX *c, smbc_purge_cached_srv_fn fn)
899 c->cache.purge_cached_server_fn = fn;
903 * Callable functions for files.
907 smbc_getFunctionOpen(SMBCCTX *c)
909 return c->posix_emu.open_fn;
913 smbc_setFunctionOpen(SMBCCTX *c, smbc_open_fn fn)
915 c->posix_emu.open_fn = fn;
919 smbc_getFunctionCreat(SMBCCTX *c)
921 return c->posix_emu.creat_fn;
925 smbc_setFunctionCreat(SMBCCTX *c, smbc_creat_fn fn)
927 c->posix_emu.creat_fn = fn;
931 smbc_getFunctionRead(SMBCCTX *c)
933 return c->posix_emu.read_fn;
937 smbc_setFunctionRead(SMBCCTX *c, smbc_read_fn fn)
939 c->posix_emu.read_fn = fn;
943 smbc_getFunctionWrite(SMBCCTX *c)
945 return c->posix_emu.write_fn;
949 smbc_setFunctionWrite(SMBCCTX *c, smbc_write_fn fn)
951 c->posix_emu.write_fn = fn;
955 smbc_getFunctionUnlink(SMBCCTX *c)
957 return c->posix_emu.unlink_fn;
961 smbc_setFunctionUnlink(SMBCCTX *c, smbc_unlink_fn fn)
963 c->posix_emu.unlink_fn = fn;
967 smbc_getFunctionRename(SMBCCTX *c)
969 return c->posix_emu.rename_fn;
973 smbc_setFunctionRename(SMBCCTX *c, smbc_rename_fn fn)
975 c->posix_emu.rename_fn = fn;
979 smbc_getFunctionLseek(SMBCCTX *c)
981 return c->posix_emu.lseek_fn;
985 smbc_setFunctionLseek(SMBCCTX *c, smbc_lseek_fn fn)
987 c->posix_emu.lseek_fn = fn;
991 smbc_getFunctionStat(SMBCCTX *c)
993 return c->posix_emu.stat_fn;
997 smbc_setFunctionStat(SMBCCTX *c, smbc_stat_fn fn)
999 c->posix_emu.stat_fn = fn;
1003 smbc_getFunctionFstat(SMBCCTX *c)
1005 return c->posix_emu.fstat_fn;
1009 smbc_setFunctionFstat(SMBCCTX *c, smbc_fstat_fn fn)
1011 c->posix_emu.fstat_fn = fn;
1015 smbc_getFunctionFtruncate(SMBCCTX *c)
1017 return c->posix_emu.ftruncate_fn;
1021 smbc_setFunctionFtruncate(SMBCCTX *c, smbc_ftruncate_fn fn)
1023 c->posix_emu.ftruncate_fn = fn;
1027 smbc_getFunctionClose(SMBCCTX *c)
1029 return c->posix_emu.close_fn;
1033 smbc_setFunctionClose(SMBCCTX *c, smbc_close_fn fn)
1035 c->posix_emu.close_fn = fn;
1040 * Callable functions for directories.
1044 smbc_getFunctionOpendir(SMBCCTX *c)
1046 return c->posix_emu.opendir_fn;
1050 smbc_setFunctionOpendir(SMBCCTX *c, smbc_opendir_fn fn)
1052 c->posix_emu.opendir_fn = fn;
1056 smbc_getFunctionClosedir(SMBCCTX *c)
1058 return c->posix_emu.closedir_fn;
1062 smbc_setFunctionClosedir(SMBCCTX *c, smbc_closedir_fn fn)
1064 c->posix_emu.closedir_fn = fn;
1068 smbc_getFunctionReaddir(SMBCCTX *c)
1070 return c->posix_emu.readdir_fn;
1074 smbc_setFunctionReaddir(SMBCCTX *c, smbc_readdir_fn fn)
1076 c->posix_emu.readdir_fn = fn;
1080 smbc_getFunctionGetdents(SMBCCTX *c)
1082 return c->posix_emu.getdents_fn;
1086 smbc_setFunctionGetdents(SMBCCTX *c, smbc_getdents_fn fn)
1088 c->posix_emu.getdents_fn = fn;
1092 smbc_getFunctionMkdir(SMBCCTX *c)
1094 return c->posix_emu.mkdir_fn;
1098 smbc_setFunctionMkdir(SMBCCTX *c, smbc_mkdir_fn fn)
1100 c->posix_emu.mkdir_fn = fn;
1104 smbc_getFunctionRmdir(SMBCCTX *c)
1106 return c->posix_emu.rmdir_fn;
1110 smbc_setFunctionRmdir(SMBCCTX *c, smbc_rmdir_fn fn)
1112 c->posix_emu.rmdir_fn = fn;
1116 smbc_getFunctionTelldir(SMBCCTX *c)
1118 return c->posix_emu.telldir_fn;
1122 smbc_setFunctionTelldir(SMBCCTX *c, smbc_telldir_fn fn)
1124 c->posix_emu.telldir_fn = fn;
1128 smbc_getFunctionLseekdir(SMBCCTX *c)
1130 return c->posix_emu.lseekdir_fn;
1134 smbc_setFunctionLseekdir(SMBCCTX *c, smbc_lseekdir_fn fn)
1136 c->posix_emu.lseekdir_fn = fn;
1140 smbc_getFunctionFstatdir(SMBCCTX *c)
1142 return c->posix_emu.fstatdir_fn;
1146 smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn)
1148 c->posix_emu.fstatdir_fn = fn;
1153 * Callable functions applicable to both files and directories.
1157 smbc_getFunctionChmod(SMBCCTX *c)
1159 return c->posix_emu.chmod_fn;
1163 smbc_setFunctionChmod(SMBCCTX *c, smbc_chmod_fn fn)
1165 c->posix_emu.chmod_fn = fn;
1169 smbc_getFunctionUtimes(SMBCCTX *c)
1171 return c->posix_emu.utimes_fn;
1175 smbc_setFunctionUtimes(SMBCCTX *c, smbc_utimes_fn fn)
1177 c->posix_emu.utimes_fn = fn;
1181 smbc_getFunctionSetxattr(SMBCCTX *c)
1183 return c->posix_emu.setxattr_fn;
1187 smbc_setFunctionSetxattr(SMBCCTX *c, smbc_setxattr_fn fn)
1189 c->posix_emu.setxattr_fn = fn;
1193 smbc_getFunctionGetxattr(SMBCCTX *c)
1195 return c->posix_emu.getxattr_fn;
1199 smbc_setFunctionGetxattr(SMBCCTX *c, smbc_getxattr_fn fn)
1201 c->posix_emu.getxattr_fn = fn;
1205 smbc_getFunctionRemovexattr(SMBCCTX *c)
1207 return c->posix_emu.removexattr_fn;
1211 smbc_setFunctionRemovexattr(SMBCCTX *c, smbc_removexattr_fn fn)
1213 c->posix_emu.removexattr_fn = fn;
1217 smbc_getFunctionListxattr(SMBCCTX *c)
1219 return c->posix_emu.listxattr_fn;
1223 smbc_setFunctionListxattr(SMBCCTX *c, smbc_listxattr_fn fn)
1225 c->posix_emu.listxattr_fn = fn;
1230 * Callable functions related to printing
1234 smbc_getFunctionPrintFile(SMBCCTX *c)
1236 return c->printing.print_file_fn;
1240 smbc_setFunctionPrintFile(SMBCCTX *c, smbc_print_file_fn fn)
1242 c->printing.print_file_fn = fn;
1245 smbc_open_print_job_fn
1246 smbc_getFunctionOpenPrintJob(SMBCCTX *c)
1248 return c->printing.open_print_job_fn;
1252 smbc_setFunctionOpenPrintJob(SMBCCTX *c,
1253 smbc_open_print_job_fn fn)
1255 c->printing.open_print_job_fn = fn;
1258 smbc_list_print_jobs_fn
1259 smbc_getFunctionListPrintJobs(SMBCCTX *c)
1261 return c->printing.list_print_jobs_fn;
1265 smbc_setFunctionListPrintJobs(SMBCCTX *c,
1266 smbc_list_print_jobs_fn fn)
1268 c->printing.list_print_jobs_fn = fn;
1271 smbc_unlink_print_job_fn
1272 smbc_getFunctionUnlinkPrintJob(SMBCCTX *c)
1274 return c->printing.unlink_print_job_fn;
1278 smbc_setFunctionUnlinkPrintJob(SMBCCTX *c,
1279 smbc_unlink_print_job_fn fn)
1281 c->printing.unlink_print_job_fn = fn;