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)
46 * All newly added context fields should be placed in SMBC_internal_data,
47 * not directly in SMBCCTX.
50 # define OLD(field) context->field
52 # define NEW(field) context->internal->field
54 context = SMB_MALLOC_P(SMBCCTX);
60 ZERO_STRUCTP(context);
62 context->internal = SMB_MALLOC_P(struct SMBC_internal_data);
63 if (!context->internal) {
69 /* Initialize the context and establish reasonable defaults */
70 ZERO_STRUCTP(context->internal);
72 OLD(config.debug) = 0;
73 OLD(config.timeout) = 20000; /* 20 seconds */
75 NEW(full_time_names) = False;
76 NEW(share_mode) = SMBC_SHAREMODE_DENY_NONE;
77 NEW(smb_encryption_level) = 0;
78 NEW(browse_max_lmb_count) = 3; /* # LMBs to query */
79 NEW(urlencode_readdir_entries) = False;
80 NEW(one_share_per_server) = False;
82 OLD(server.get_auth_data_fn) = SMBC_get_auth_data;
83 OLD(server.check_server_fn) = SMBC_check_server;
84 OLD(server.remove_unused_server_fn) = SMBC_remove_unused_server;
86 OLD(cache.server_cache_data) = NULL;
87 OLD(cache.add_cached_server_fn) = SMBC_add_cached_server;
88 OLD(cache.get_cached_server_fn) = SMBC_get_cached_server;
89 OLD(cache.remove_cached_server_fn) = SMBC_remove_cached_server;
90 OLD(cache.purge_cached_servers_fn) = SMBC_purge_cached_servers;
92 OLD(posix_emu.open_fn) = SMBC_open_ctx;
93 OLD(posix_emu.creat_fn) = SMBC_creat_ctx;
94 OLD(posix_emu.read_fn) = SMBC_read_ctx;
95 OLD(posix_emu.write_fn) = SMBC_write_ctx;
96 OLD(posix_emu.close_fn) = SMBC_close_ctx;
97 OLD(posix_emu.unlink_fn) = SMBC_unlink_ctx;
98 OLD(posix_emu.rename_fn) = SMBC_rename_ctx;
99 OLD(posix_emu.lseek_fn) = SMBC_lseek_ctx;
100 NEW(posix_emu.ftruncate_fn) = SMBC_ftruncate_ctx;
101 OLD(posix_emu.stat_fn) = SMBC_stat_ctx;
102 OLD(posix_emu.fstat_fn) = SMBC_fstat_ctx;
103 OLD(posix_emu.opendir_fn) = SMBC_opendir_ctx;
104 OLD(posix_emu.closedir_fn) = SMBC_closedir_ctx;
105 OLD(posix_emu.readdir_fn) = SMBC_readdir_ctx;
106 OLD(posix_emu.getdents_fn) = SMBC_getdents_ctx;
107 OLD(posix_emu.mkdir_fn) = SMBC_mkdir_ctx;
108 OLD(posix_emu.rmdir_fn) = SMBC_rmdir_ctx;
109 OLD(posix_emu.telldir_fn) = SMBC_telldir_ctx;
110 OLD(posix_emu.lseekdir_fn) = SMBC_lseekdir_ctx;
111 OLD(posix_emu.fstatdir_fn) = SMBC_fstatdir_ctx;
112 OLD(posix_emu.chmod_fn) = SMBC_chmod_ctx;
113 OLD(posix_emu.utimes_fn) = SMBC_utimes_ctx;
114 OLD(posix_emu.setxattr_fn) = SMBC_setxattr_ctx;
115 OLD(posix_emu.getxattr_fn) = SMBC_getxattr_ctx;
116 OLD(posix_emu.removexattr_fn) = SMBC_removexattr_ctx;
117 OLD(posix_emu.listxattr_fn) = SMBC_listxattr_ctx;
119 OLD(printing.open_print_job_fn) = SMBC_open_print_job_ctx;
120 OLD(printing.print_file_fn) = SMBC_print_file_ctx;
121 OLD(printing.list_print_jobs_fn) = SMBC_list_print_jobs_ctx;
122 OLD(printing.unlink_print_job_fn) = SMBC_unlink_print_job_ctx;
132 * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed
133 * and thus you'll be leaking memory if not handled properly.
137 smbc_free_context(SMBCCTX *context,
147 DEBUG(1,("Performing aggressive shutdown.\n"));
149 f = context->internal->files;
151 (context->posix_emu.close_fn)(context, f);
154 context->internal->files = NULL;
156 /* First try to remove the servers the nice way. */
157 if (context->cache.purge_cached_servers_fn(context)) {
160 DEBUG(1, ("Could not purge all servers, "
161 "Nice way shutdown failed.\n"));
162 s = context->internal->servers;
164 DEBUG(1, ("Forced shutdown: %p (fd=%d)\n",
166 cli_shutdown(s->cli);
167 (context->cache.remove_cached_server_fn)(context,
170 DLIST_REMOVE(context->internal->servers, s);
174 context->internal->servers = NULL;
178 /* This is the polite way */
179 if ((context->cache.purge_cached_servers_fn)(context)) {
180 DEBUG(1, ("Could not purge all servers, "
181 "free_context failed.\n"));
185 if (context->internal->servers) {
186 DEBUG(1, ("Active servers in context, "
187 "free_context failed.\n"));
191 if (context->internal->files) {
192 DEBUG(1, ("Active files in context, "
193 "free_context failed.\n"));
199 /* Things we have to clean up */
200 SAFE_FREE(context->config.workgroup);
201 SAFE_FREE(context->config.netbios_name);
202 SAFE_FREE(context->config.user);
204 DEBUG(3, ("Context %p successfully freed\n", context));
211 * Each time the context structure is changed, we have binary backward
212 * compatibility issues. Instead of modifying the public portions of the
213 * context structure to add new options, instead, we put them in the internal
214 * portion of the context structure and provide a set function for these new
218 smbc_option_set(SMBCCTX *context,
220 ... /* option_value */)
226 smbc_get_auth_data_with_context_fn auth_fn;
231 va_start(ap, option_name);
233 if (strcmp(option_name, "debug_to_stderr") == 0) {
235 * Log to standard error instead of standard output.
237 option_value.b = (bool) va_arg(ap, int);
238 context->internal->debug_stderr = option_value.b;
240 } else if (strcmp(option_name, "full_time_names") == 0) {
242 * Use new-style time attribute names, e.g. WRITE_TIME rather
243 * than the old-style names such as M_TIME. This allows also
244 * setting/getting CREATE_TIME which was previously
245 * unimplemented. (Note that the old C_TIME was supposed to
246 * be CHANGE_TIME but was confused and sometimes referred to
249 option_value.b = (bool) va_arg(ap, int);
250 context->internal->full_time_names = option_value.b;
252 } else if (strcmp(option_name, "open_share_mode") == 0) {
254 * The share mode to use for files opened with
255 * SMBC_open_ctx(). The default is SMBC_SHAREMODE_DENY_NONE.
257 option_value.i = va_arg(ap, int);
258 context->internal->share_mode = (smbc_share_mode) option_value.i;
260 } else if (strcmp(option_name, "user_data") == 0) {
262 * Save a user data handle which may be retrieved by the user
263 * with smbc_option_get()
265 option_value.v = va_arg(ap, void *);
266 context->internal->user_data = option_value.v;
267 } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
269 * Save an encoded value for encryption level.
270 * 0 = off, 1 = attempt, 2 = required.
272 option_value.s = va_arg(ap, const char *);
273 if (strcmp(option_value.s, "none") == 0) {
274 context->internal->smb_encryption_level = 0;
275 } else if (strcmp(option_value.s, "request") == 0) {
276 context->internal->smb_encryption_level = 1;
277 } else if (strcmp(option_value.s, "require") == 0) {
278 context->internal->smb_encryption_level = 2;
280 } else if (strcmp(option_name, "browse_max_lmb_count") == 0) {
282 * From how many local master browsers should the list of
283 * workgroups be retrieved? It can take up to 12 minutes or
284 * longer after a server becomes a local master browser, for
285 * it to have the entire browse list (the list of
286 * workgroups/domains) from an entire network. Since a client
287 * never knows which local master browser will be found first,
288 * the one which is found first and used to retrieve a browse
289 * list may have an incomplete or empty browse list. By
290 * requesting the browse list from multiple local master
291 * browsers, a more complete list can be generated. For small
292 * networks (few workgroups), it is recommended that this
293 * value be set to 0, causing the browse lists from all found
294 * local master browsers to be retrieved and merged. For
295 * networks with many workgroups, a suitable value for this
296 * variable is probably somewhere around 3. (Default: 3).
298 option_value.i = va_arg(ap, int);
299 context->internal->browse_max_lmb_count = option_value.i;
301 } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) {
303 * There is a difference in the desired return strings from
304 * smbc_readdir() depending upon whether the filenames are to
305 * be displayed to the user, or whether they are to be
306 * appended to the path name passed to smbc_opendir() to call
307 * a further smbc_ function (e.g. open the file with
308 * smbc_open()). In the former case, the filename should be
309 * in "human readable" form. In the latter case, the smbc_
310 * functions expect a URL which must be url-encoded. Those
311 * functions decode the URL. If, for example, smbc_readdir()
312 * returned a file name of "abc%20def.txt", passing a path
313 * with this file name attached to smbc_open() would cause
314 * smbc_open to attempt to open the file "abc def.txt" since
315 * the %20 is decoded into a space.
317 * Set this option to True if the names returned by
318 * smbc_readdir() should be url-encoded such that they can be
319 * passed back to another smbc_ call. Set it to False if the
320 * names returned by smbc_readdir() are to be presented to the
323 * For backwards compatibility, this option defaults to False.
325 option_value.b = (bool) va_arg(ap, int);
326 context->internal->urlencode_readdir_entries = option_value.b;
328 } else if (strcmp(option_name, "one_share_per_server") == 0) {
330 * Some Windows versions appear to have a limit to the number
331 * of concurrent SESSIONs and/or TREE CONNECTions. In
332 * one-shot programs (i.e. the program runs and then quickly
333 * ends, thereby shutting down all connections), it is
334 * probably reasonable to establish a new connection for each
335 * share. In long-running applications, the limitation can be
336 * avoided by using only a single connection to each server,
337 * and issuing a new TREE CONNECT when the share is accessed.
339 option_value.b = (bool) va_arg(ap, int);
340 context->options.one_share_per_server = option_value.b;
342 } else if (strcmp(option_name, "use_kerberos") == 0) {
343 option_value.b = (bool) va_arg(ap, int);
344 if (option_value.b) {
345 context->flags.bits |= SMB_CTX_FLAG_USE_KERBEROS;
347 context->flags.bits &= ~SMB_CTX_FLAG_USE_KERBEROS;
350 } else if (strcmp(option_name, "fallback_after_kerberos") == 0) {
351 option_value.b = (bool) va_arg(ap, int);
352 if (option_value.b) {
353 context->flags.bits |= SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS;
355 context->flags.bits &= ~SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS;
358 } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) {
359 option_value.b = (bool) va_arg(ap, int);
360 if (option_value.b) {
361 context->flags.bits |= SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON;
363 context->flags.bits &= ~SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON;
372 * Retrieve the current value of an option
375 smbc_option_get(SMBCCTX *context,
380 if (strcmp(option_name, "debug_stderr") == 0) {
382 * Log to standard error instead of standard output.
384 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
385 return (void *) (intptr_t) context->internal->debug_stderr;
387 return (void *) context->internal->debug_stderr;
390 } else if (strcmp(option_name, "full_time_names") == 0) {
392 * Use new-style time attribute names, e.g. WRITE_TIME rather
393 * than the old-style names such as M_TIME. This allows also
394 * setting/getting CREATE_TIME which was previously
395 * unimplemented. (Note that the old C_TIME was supposed to
396 * be CHANGE_TIME but was confused and sometimes referred to
399 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
400 return (void *) (intptr_t) context->internal->full_time_names;
402 return (void *) context->internal->full_time_names;
405 } else if (strcmp(option_name, "user_data") == 0) {
407 * Return the user data handle which was saved by the user
408 * with smbc_option_set()
410 return context->internal->user_data;
412 } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
414 * Return the current smb encrypt negotiate option as a string.
416 switch (context->internal->smb_encryption_level) {
418 return (void *) "none";
420 return (void *) "request";
422 return (void *) "require";
425 } else if (strcmp(option_name, "smb_encrypt_on") == 0) {
427 * Return the current smb encrypt status option as a bool.
428 * false = off, true = on. We don't know what server is
429 * being requested, so we only return true if all servers
430 * are using an encrypted connection.
433 unsigned int num_servers = 0;
435 for (s = context->internal->servers; s; s = s->next) {
437 if (s->cli->trans_enc_state == NULL) {
438 return (void *)false;
441 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
442 return (void *) (intptr_t) (bool) (num_servers > 0);
444 return (void *) (bool) (num_servers > 0);
447 } else if (strcmp(option_name, "browse_max_lmb_count") == 0) {
449 * From how many local master browsers should the list of
450 * workgroups be retrieved? It can take up to 12 minutes or
451 * longer after a server becomes a local master browser, for
452 * it to have the entire browse list (the list of
453 * workgroups/domains) from an entire network. Since a client
454 * never knows which local master browser will be found first,
455 * the one which is found first and used to retrieve a browse
456 * list may have an incomplete or empty browse list. By
457 * requesting the browse list from multiple local master
458 * browsers, a more complete list can be generated. For small
459 * networks (few workgroups), it is recommended that this
460 * value be set to 0, causing the browse lists from all found
461 * local master browsers to be retrieved and merged. For
462 * networks with many workgroups, a suitable value for this
463 * variable is probably somewhere around 3. (Default: 3).
465 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
466 return (void *) (intptr_t) context->internal->browse_max_lmb_count;
468 return (void *) context->internal->browse_max_lmb_count;
471 } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) {
473 * There is a difference in the desired return strings from
474 * smbc_readdir() depending upon whether the filenames are to
475 * be displayed to the user, or whether they are to be
476 * appended to the path name passed to smbc_opendir() to call
477 * a further smbc_ function (e.g. open the file with
478 * smbc_open()). In the former case, the filename should be
479 * in "human readable" form. In the latter case, the smbc_
480 * functions expect a URL which must be url-encoded. Those
481 * functions decode the URL. If, for example, smbc_readdir()
482 * returned a file name of "abc%20def.txt", passing a path
483 * with this file name attached to smbc_open() would cause
484 * smbc_open to attempt to open the file "abc def.txt" since
485 * the %20 is decoded into a space.
487 * Set this option to True if the names returned by
488 * smbc_readdir() should be url-encoded such that they can be
489 * passed back to another smbc_ call. Set it to False if the
490 * names returned by smbc_readdir() are to be presented to the
493 * For backwards compatibility, this option defaults to False.
495 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
496 return (void *)(intptr_t) context->internal->urlencode_readdir_entries;
498 return (void *) (bool) context->internal->urlencode_readdir_entries;
501 } else if (strcmp(option_name, "one_share_per_server") == 0) {
503 * Some Windows versions appear to have a limit to the number
504 * of concurrent SESSIONs and/or TREE CONNECTions. In
505 * one-shot programs (i.e. the program runs and then quickly
506 * ends, thereby shutting down all connections), it is
507 * probably reasonable to establish a new connection for each
508 * share. In long-running applications, the limitation can be
509 * avoided by using only a single connection to each server,
510 * and issuing a new TREE CONNECT when the share is accessed.
512 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
513 return (void *) (intptr_t) context->internal->one_share_per_server;
515 return (void *) (bool) context->internal->one_share_per_server;
518 } else if (strcmp(option_name, "use_kerberos") == 0) {
519 bits = context->flags.bits;
520 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
521 return (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS
522 ? (void *) (intptr_t) 1
523 : (void *) (intptr_t) 0);
525 return (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS
527 : (void *) (bool) 0);
530 } else if (strcmp(option_name, "fallback_after_kerberos") == 0) {
531 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
532 return (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS
533 ? (void *) (intptr_t) 1
534 : (void *) (intptr_t) 0);
536 return (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS
538 : (void *) (bool) 0);
541 } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) {
542 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
543 return (context->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON
544 ? (void *) (intptr_t) 1
545 : (void *) (intptr_t) 0);
547 return (context->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON
549 : (void *) (bool) 0);
558 * Initialize the library, etc.
560 * We accept a struct containing handle information.
561 * valid values for info->debug from 0 to 100,
562 * and insist that info->fn must be non-null.
565 smbc_init_context(SMBCCTX *context)
570 extern bool in_client;
577 /* Do not initialise the same client twice */
578 if (context->internal->initialized) {
582 if (!context->server.get_auth_data_fn ||
583 context->config.debug < 0 ||
584 context->config.debug > 100) {
591 if (!SMBC_initialized) {
593 * Do some library-wide intializations the first time we get
596 bool conf_loaded = False;
597 TALLOC_CTX *frame = talloc_stackframe();
599 /* Set this to what the user wants */
600 DEBUGLEVEL = context->config.debug;
604 setup_logging("libsmbclient", True);
605 if (context->internal->debug_stderr) {
607 x_setbuf(x_stderr, NULL);
610 /* Here we would open the smb.conf file if needed ... */
612 in_client = True; /* FIXME, make a param */
614 home = getenv("HOME");
617 if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) {
618 if (lp_load(conf, True, False, False, True)) {
621 DEBUG(5, ("Could not load config file: %s\n",
630 * Well, if that failed, try the get_dyn_CONFIGFILE
631 * Which points to the standard locn, and if that
632 * fails, silently ignore it and use the internal
636 if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) {
637 DEBUG(5, ("Could not load config file: %s\n",
638 get_dyn_CONFIGFILE()));
642 * We loaded the global config file. Now lets
643 * load user-specific modifications to the
647 "%s/.smb/smb.conf.append",
649 if (!lp_load(conf, True, False, False, False)) {
651 ("Could not append config file: "
660 load_interfaces(); /* Load the list of interfaces ... */
662 reopen_logs(); /* Get logging working ... */
665 * Block SIGPIPE (from lib/util_sock.c: write())
666 * It is not needed and should not stop execution
668 BlockSignals(True, SIGPIPE);
670 /* Done with one-time initialisation */
671 SMBC_initialized = 1;
676 if (!context->config.user) {
678 * FIXME: Is this the best way to get the user info?
680 user = getenv("USER");
681 /* walk around as "guest" if no username can be found */
682 if (!user) context->config.user = SMB_STRDUP("guest");
683 else context->config.user = SMB_STRDUP(user);
686 if (!context->config.netbios_name) {
688 * We try to get our netbios name from the config. If that
689 * fails we fall back on constructing our netbios name from
692 if (global_myname()) {
693 context->config.netbios_name = SMB_STRDUP(global_myname());
697 * Hmmm, I want to get hostname as well, but I am too
698 * lazy for the moment
701 context->config.netbios_name = (char *)SMB_MALLOC(17);
702 if (!context->config.netbios_name) {
706 slprintf(context->config.netbios_name, 16,
707 "smbc%s%d", context->config.user, pid);
711 DEBUG(1, ("Using netbios name %s.\n", context->config.netbios_name));
713 if (!context->config.workgroup) {
714 if (lp_workgroup()) {
715 context->config.workgroup = SMB_STRDUP(lp_workgroup());
718 /* TODO: Think about a decent default workgroup */
719 context->config.workgroup = SMB_STRDUP("samba");
723 DEBUG(1, ("Using workgroup %s.\n", context->config.workgroup));
725 /* shortest timeout is 1 second */
726 if (context->config.timeout > 0 && context->config.timeout < 1000)
727 context->config.timeout = 1000;
730 * FIXME: Should we check the function pointers here?
733 context->internal->initialized = True;
739 /* Return the verion of samba, and thus libsmbclient */
743 return samba_version_string();
747 /** Get the netbios name used for making connections */
749 smbc_getNetbiosName(SMBCCTX *c)
751 return c->config.netbios_name;
754 /** Set the netbios name used for making connections */
756 smbc_setNetbiosName(SMBCCTX *c, char * netbios_name)
758 c->config.netbios_name = netbios_name;
761 /** Get the workgroup used for making connections */
763 smbc_getWorkgroup(SMBCCTX *c)
765 return c->config.workgroup;
768 /** Set the workgroup used for making connections */
770 smbc_setWorkgroup(SMBCCTX *c, char * workgroup)
772 c->config.workgroup = workgroup;
775 /** Get the username used for making connections */
777 smbc_getUser(SMBCCTX *c)
779 return c->config.user;
782 /** Set the username used for making connections */
784 smbc_setUser(SMBCCTX *c, char * user)
786 c->config.user = user;
789 /** Get the debug level */
791 smbc_getDebug(SMBCCTX *c)
793 return c->config.debug;
796 /** Set the debug level */
798 smbc_setDebug(SMBCCTX *c, int debug)
800 c->config.debug = debug;
804 * Get the timeout used for waiting on connections and response data
808 smbc_getTimeout(SMBCCTX *c)
810 return c->config.timeout;
814 * Set the timeout used for waiting on connections and response data
818 smbc_setTimeout(SMBCCTX *c, int timeout)
820 c->config.timeout = timeout;
823 /** Get the function for obtaining authentication data */
825 smbc_get_auth_data_fn
826 smbc_getFunctionAuthData(SMBCCTX *c)
828 return c->server.get_auth_data_fn;
831 /** Set the function for obtaining authentication data */
833 smbc_setFunctionAuthData(SMBCCTX *c, smbc_get_auth_data_fn fn)
835 c->server.get_auth_data_fn = fn;
838 /** Get the function for checking if a server is still good */
840 smbc_getFunctionCheckServer(SMBCCTX *c)
842 return c->server.check_server_fn;
845 /** Set the function for checking if a server is still good */
847 smbc_setFunctionCheckServer(SMBCCTX *c, smbc_check_server_fn fn)
849 c->server.check_server_fn = fn;
852 /** Get the function for removing a server if unused */
853 smbc_remove_unused_server_fn
854 smbc_getFunctionRemoveUnusedServer(SMBCCTX *c)
856 return c->server.remove_unused_server_fn;
859 /** Set the function for removing a server if unused */
861 smbc_setFunctionRemoveUnusedServer(SMBCCTX *c,
862 smbc_remove_unused_server_fn fn)
864 c->server.remove_unused_server_fn = fn;
867 /** Get the function to store private data of the server cache */
869 smbc_server_cache * smbc_getServerCacheData(SMBCCTX *c)
871 return c->cache.server_cache_data;
874 /** Set the function to store private data of the server cache */
876 smbc_setServerCacheData(SMBCCTX *c, struct smbc_server_cache * cache)
878 c->cache.server_cache_data = cache;
882 /** Get the function for adding a cached server */
883 smbc_add_cached_srv_fn
884 smbc_getFunctionAddCachedServer(SMBCCTX *c)
886 return c->cache.add_cached_server_fn;
889 /** Set the function for adding a cached server */
891 smbc_setFunctionAddCachedServer(SMBCCTX *c, smbc_add_cached_srv_fn fn)
893 c->cache.add_cached_server_fn = fn;
896 /** Get the function for server cache lookup */
897 smbc_get_cached_srv_fn
898 smbc_getFunctionGetCachedServer(SMBCCTX *c)
900 return c->cache.get_cached_server_fn;
903 /** Set the function for server cache lookup */
905 smbc_setFunctionGetCachedServer(SMBCCTX *c, smbc_get_cached_srv_fn fn)
907 c->cache.get_cached_server_fn = fn;
910 /** Get the function for server cache removal */
911 smbc_remove_cached_srv_fn
912 smbc_getFunctionRemoveCachedServer(SMBCCTX *c)
914 return c->cache.remove_cached_server_fn;
917 /** Set the function for server cache removal */
919 smbc_setFunctionRemoveCachedServer(SMBCCTX *c,
920 smbc_remove_cached_srv_fn fn)
922 c->cache.remove_cached_server_fn = fn;
926 * Get the function for server cache purging. This function tries to
927 * remove all cached servers (e.g. on disconnect)
929 smbc_purge_cached_srv_fn
930 smbc_getFunctionPurgeCachedServers(SMBCCTX *c)
932 return c->cache.purge_cached_servers_fn;
936 * Set the function for server cache purging. This function tries to
937 * remove all cached servers (e.g. on disconnect)
940 smbc_setFunctionPurgeCachedServers(SMBCCTX *c, smbc_purge_cached_srv_fn fn)
942 c->cache.purge_cached_servers_fn = fn;
946 * Callable functions for files.
950 smbc_getFunctionOpen(SMBCCTX *c)
952 return c->posix_emu.open_fn;
956 smbc_setFunctionOpen(SMBCCTX *c, smbc_open_fn fn)
958 c->posix_emu.open_fn = fn;
962 smbc_getFunctionCreat(SMBCCTX *c)
964 return c->posix_emu.creat_fn;
968 smbc_setFunctionCreat(SMBCCTX *c, smbc_creat_fn fn)
970 c->posix_emu.creat_fn = fn;
974 smbc_getFunctionRead(SMBCCTX *c)
976 return c->posix_emu.read_fn;
980 smbc_setFunctionRead(SMBCCTX *c, smbc_read_fn fn)
982 c->posix_emu.read_fn = fn;
986 smbc_getFunctionWrite(SMBCCTX *c)
988 return c->posix_emu.write_fn;
992 smbc_setFunctionWrite(SMBCCTX *c, smbc_write_fn fn)
994 c->posix_emu.write_fn = fn;
998 smbc_getFunctionUnlink(SMBCCTX *c)
1000 return c->posix_emu.unlink_fn;
1004 smbc_setFunctionUnlink(SMBCCTX *c, smbc_unlink_fn fn)
1006 c->posix_emu.unlink_fn = fn;
1010 smbc_getFunctionRename(SMBCCTX *c)
1012 return c->posix_emu.rename_fn;
1016 smbc_setFunctionRename(SMBCCTX *c, smbc_rename_fn fn)
1018 c->posix_emu.rename_fn = fn;
1022 smbc_getFunctionLseek(SMBCCTX *c)
1024 return c->posix_emu.lseek_fn;
1028 smbc_setFunctionLseek(SMBCCTX *c, smbc_lseek_fn fn)
1030 c->posix_emu.lseek_fn = fn;
1034 smbc_getFunctionStat(SMBCCTX *c)
1036 return c->posix_emu.stat_fn;
1040 smbc_setFunctionStat(SMBCCTX *c, smbc_stat_fn fn)
1042 c->posix_emu.stat_fn = fn;
1046 smbc_getFunctionFstat(SMBCCTX *c)
1048 return c->posix_emu.fstat_fn;
1052 smbc_setFunctionFstat(SMBCCTX *c, smbc_fstat_fn fn)
1054 c->posix_emu.fstat_fn = fn;
1058 smbc_getFunctionFtruncate(SMBCCTX *c)
1060 return c->internal->posix_emu.ftruncate_fn;
1064 smbc_setFunctionFtruncate(SMBCCTX *c, smbc_ftruncate_fn fn)
1066 c->internal->posix_emu.ftruncate_fn = fn;
1070 smbc_getFunctionClose(SMBCCTX *c)
1072 return c->posix_emu.close_fn;
1076 smbc_setFunctionClose(SMBCCTX *c, smbc_close_fn fn)
1078 c->posix_emu.close_fn = fn;
1083 * Callable functions for directories.
1087 smbc_getFunctionOpendir(SMBCCTX *c)
1089 return c->posix_emu.opendir_fn;
1093 smbc_setFunctionOpendir(SMBCCTX *c, smbc_opendir_fn fn)
1095 c->posix_emu.opendir_fn = fn;
1099 smbc_getFunctionClosedir(SMBCCTX *c)
1101 return c->posix_emu.closedir_fn;
1105 smbc_setFunctionClosedir(SMBCCTX *c, smbc_closedir_fn fn)
1107 c->posix_emu.closedir_fn = fn;
1111 smbc_getFunctionReaddir(SMBCCTX *c)
1113 return c->posix_emu.readdir_fn;
1117 smbc_setFunctionReaddir(SMBCCTX *c, smbc_readdir_fn fn)
1119 c->posix_emu.readdir_fn = fn;
1123 smbc_getFunctionGetdents(SMBCCTX *c)
1125 return c->posix_emu.getdents_fn;
1129 smbc_setFunctionGetdents(SMBCCTX *c, smbc_getdents_fn fn)
1131 c->posix_emu.getdents_fn = fn;
1135 smbc_getFunctionMkdir(SMBCCTX *c)
1137 return c->posix_emu.mkdir_fn;
1141 smbc_setFunctionMkdir(SMBCCTX *c, smbc_mkdir_fn fn)
1143 c->posix_emu.mkdir_fn = fn;
1147 smbc_getFunctionRmdir(SMBCCTX *c)
1149 return c->posix_emu.rmdir_fn;
1153 smbc_setFunctionRmdir(SMBCCTX *c, smbc_rmdir_fn fn)
1155 c->posix_emu.rmdir_fn = fn;
1159 smbc_getFunctionTelldir(SMBCCTX *c)
1161 return c->posix_emu.telldir_fn;
1165 smbc_setFunctionTelldir(SMBCCTX *c, smbc_telldir_fn fn)
1167 c->posix_emu.telldir_fn = fn;
1171 smbc_getFunctionLseekdir(SMBCCTX *c)
1173 return c->posix_emu.lseekdir_fn;
1177 smbc_setFunctionLseekdir(SMBCCTX *c, smbc_lseekdir_fn fn)
1179 c->posix_emu.lseekdir_fn = fn;
1183 smbc_getFunctionFstatdir(SMBCCTX *c)
1185 return c->posix_emu.fstatdir_fn;
1189 smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn)
1191 c->posix_emu.fstatdir_fn = fn;
1196 * Callable functions applicable to both files and directories.
1200 smbc_getFunctionChmod(SMBCCTX *c)
1202 return c->posix_emu.chmod_fn;
1206 smbc_setFunctionChmod(SMBCCTX *c, smbc_chmod_fn fn)
1208 c->posix_emu.chmod_fn = fn;
1212 smbc_getFunctionUtimes(SMBCCTX *c)
1214 return c->posix_emu.utimes_fn;
1218 smbc_setFunctionUtimes(SMBCCTX *c, smbc_utimes_fn fn)
1220 c->posix_emu.utimes_fn = fn;
1224 smbc_getFunctionSetxattr(SMBCCTX *c)
1226 return c->posix_emu.setxattr_fn;
1230 smbc_setFunctionSetxattr(SMBCCTX *c, smbc_setxattr_fn fn)
1232 c->posix_emu.setxattr_fn = fn;
1236 smbc_getFunctionGetxattr(SMBCCTX *c)
1238 return c->posix_emu.getxattr_fn;
1242 smbc_setFunctionGetxattr(SMBCCTX *c, smbc_getxattr_fn fn)
1244 c->posix_emu.getxattr_fn = fn;
1248 smbc_getFunctionRemovexattr(SMBCCTX *c)
1250 return c->posix_emu.removexattr_fn;
1254 smbc_setFunctionRemovexattr(SMBCCTX *c, smbc_removexattr_fn fn)
1256 c->posix_emu.removexattr_fn = fn;
1260 smbc_getFunctionListxattr(SMBCCTX *c)
1262 return c->posix_emu.listxattr_fn;
1266 smbc_setFunctionListxattr(SMBCCTX *c, smbc_listxattr_fn fn)
1268 c->posix_emu.listxattr_fn = fn;
1273 * Callable functions related to printing
1277 smbc_getFunctionPrintFile(SMBCCTX *c)
1279 return c->printing.print_file_fn;
1283 smbc_setFunctionPrintFile(SMBCCTX *c, smbc_print_file_fn fn)
1285 c->printing.print_file_fn = fn;
1288 smbc_open_print_job_fn
1289 smbc_getFunctionOpenPrintJob(SMBCCTX *c)
1291 return c->printing.open_print_job_fn;
1295 smbc_setFunctionOpenPrintJob(SMBCCTX *c,
1296 smbc_open_print_job_fn fn)
1298 c->printing.open_print_job_fn = fn;
1301 smbc_list_print_jobs_fn
1302 smbc_getFunctionListPrintJobs(SMBCCTX *c)
1304 return c->printing.list_print_jobs_fn;
1308 smbc_setFunctionListPrintJobs(SMBCCTX *c,
1309 smbc_list_print_jobs_fn fn)
1311 c->printing.list_print_jobs_fn = fn;
1314 smbc_unlink_print_job_fn
1315 smbc_getFunctionUnlinkPrintJob(SMBCCTX *c)
1317 return c->printing.unlink_print_job_fn;
1321 smbc_setFunctionUnlinkPrintJob(SMBCCTX *c,
1322 smbc_unlink_print_job_fn fn)
1324 c->printing.unlink_print_job_fn = fn;