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
;