mirror of
https://github.com/samba-team/samba.git
synced 2025-03-24 10:50:22 +03:00
Additional revamped libsmbclient documentation
- Ensured that all public functions have documentation in libsmbclient.h - Reformatted for "proper" indentation - Re-added temporarily-disabled alternate authentication function capability Derrell (This used to be commit 64b7150d92849a1e1e2416b9dcc12fae8d6bea99)
This commit is contained in:
parent
4ba42cbe0f
commit
223940d9a8
@ -109,22 +109,13 @@ main(int argc, char * argv[])
|
||||
|
||||
/* Set mandatory options (is that a contradiction in terms?) */
|
||||
smbc_setDebug(context, debug);
|
||||
#if 0
|
||||
if (context_auth) {
|
||||
context->callbacks.auth_fn = NULL;
|
||||
smbc_option_set(context,
|
||||
"auth_function",
|
||||
(void *) get_auth_data_with_context_fn);
|
||||
smbc_option_set(context, "user_data", "hello world");
|
||||
smbc_setFunctionAuthDataWithContext(context,
|
||||
get_auth_data_with_context_fn);
|
||||
smbc_setOptionUserData(context, "hello world");
|
||||
} else {
|
||||
context->callbacks.auth_fn =
|
||||
(no_auth ? no_auth_data_fn : get_auth_data_fn);
|
||||
smbc_setFunctionAuthData(context, get_auth_data_fn);
|
||||
}
|
||||
#else
|
||||
#warning "temporarily remove setting alternate auth function"
|
||||
smbc_setFunctionAuthData(context,
|
||||
(no_auth ? no_auth_data_fn : get_auth_data_fn));
|
||||
#endif
|
||||
|
||||
/* If we've been asked to log to stderr instead of stdout, ... */
|
||||
if (debug_stderr) {
|
||||
|
@ -111,23 +111,23 @@ struct _SMBCFILE {
|
||||
struct SMBC_internal_data {
|
||||
|
||||
/* True when this handle is initialized */
|
||||
bool initialized;
|
||||
bool initialized;
|
||||
|
||||
#if 0 /* Left in libsmbclient.h for backward compatibility */
|
||||
/* Netbios name used for making connections */
|
||||
char * netbios_name;
|
||||
char * netbios_name;
|
||||
|
||||
/* Workgroup used for making connections */
|
||||
char * workgroup;
|
||||
char * workgroup;
|
||||
|
||||
/* Username used for making connections */
|
||||
char * user;
|
||||
char * user;
|
||||
|
||||
/* Debug level */
|
||||
int debug;
|
||||
int debug;
|
||||
|
||||
/* Connection timeout value */
|
||||
int timeout;
|
||||
int timeout;
|
||||
#endif
|
||||
|
||||
/* dirent pointer location
|
||||
@ -141,22 +141,22 @@ struct SMBC_internal_data {
|
||||
* According to <linux/limits.h>, NAME_MAX is 255. Is it longer
|
||||
* anyplace else?
|
||||
*/
|
||||
char dirent[1024];
|
||||
char dirent[1024];
|
||||
|
||||
/*
|
||||
* server connection list
|
||||
*/
|
||||
SMBCSRV * servers;
|
||||
SMBCSRV * servers;
|
||||
|
||||
/*
|
||||
* open file/dir list
|
||||
*/
|
||||
SMBCFILE * files;
|
||||
SMBCFILE * files;
|
||||
|
||||
/*
|
||||
* Log to standard error instead of the more typical standard output
|
||||
*/
|
||||
bool debug_stderr;
|
||||
bool debug_stderr;
|
||||
|
||||
/*
|
||||
* Support "Create Time" in get/set with the *xattr() functions, if
|
||||
@ -165,27 +165,34 @@ struct SMBC_internal_data {
|
||||
* CREATE_TIME. Default is FALSE, i.e. to use the old-style shorter
|
||||
* names and to not support CREATE time, for backward compatibility.
|
||||
*/
|
||||
bool full_time_names;
|
||||
bool full_time_names;
|
||||
|
||||
/*
|
||||
* The share mode of a file being opened. To match POSIX semantics
|
||||
* (and maintain backward compatibility), DENY_NONE is the default.
|
||||
*/
|
||||
smbc_share_mode share_mode;
|
||||
smbc_share_mode share_mode;
|
||||
|
||||
/*
|
||||
* Authentication function which includes the context. This will be
|
||||
* used if set; otherwise context->callbacks.auth_fn() will be used.
|
||||
*/
|
||||
smbc_get_auth_data_with_context_fn auth_fn_with_context;
|
||||
|
||||
/*
|
||||
* An opaque (to this library) user data handle which can be set
|
||||
* and retrieved with smbc_option_set() and smbc_option_get().
|
||||
*/
|
||||
void * user_data;
|
||||
void * user_data;
|
||||
|
||||
/*
|
||||
* Should we attempt UNIX smb encryption ?
|
||||
* Set to 0 if we should never attempt, set to 1 if
|
||||
* encryption requested, set to 2 if encryption required.
|
||||
*/
|
||||
int smb_encryption_level;
|
||||
smbc_smb_encrypt_level smb_encryption_level;
|
||||
|
||||
#if 0 /* Left in libsmbclient.h for backward compatibility */
|
||||
/*
|
||||
* From how many local master browsers should the list of
|
||||
* workgroups be retrieved? It can take up to 12 minutes or
|
||||
@ -203,7 +210,7 @@ struct SMBC_internal_data {
|
||||
* networks with many workgroups, a suitable value for this
|
||||
* variable is probably somewhere around 3. (Default: 3).
|
||||
*/
|
||||
int browse_max_lmb_count;
|
||||
int browse_max_lmb_count;
|
||||
|
||||
/*
|
||||
* There is a difference in the desired return strings from
|
||||
@ -228,7 +235,7 @@ struct SMBC_internal_data {
|
||||
*
|
||||
* For backwards compatibility, this option defaults to False.
|
||||
*/
|
||||
bool urlencode_readdir_entries;
|
||||
bool urlencode_readdir_entries;
|
||||
|
||||
/*
|
||||
* Some Windows versions appear to have a limit to the number
|
||||
@ -240,15 +247,14 @@ struct SMBC_internal_data {
|
||||
* avoided by using only a single connection to each server,
|
||||
* and issuing a new TREE CONNECT when the share is accessed.
|
||||
*/
|
||||
bool one_share_per_server;
|
||||
bool one_share_per_server;
|
||||
|
||||
#if 0 /* Left in libsmbclient.h (flags) for backward compatibility */
|
||||
/* Kerberos-related flags */
|
||||
bool use_kerberos;
|
||||
bool fallback_after_kerberos;
|
||||
bool use_kerberos;
|
||||
bool fallback_after_kerberos;
|
||||
|
||||
/* Don't try to do automatic anonymous login */
|
||||
bool no_auto_anonymous_login;
|
||||
bool no_auto_anonymous_login;
|
||||
|
||||
/* Server-related functions */
|
||||
struct
|
||||
|
@ -155,6 +155,21 @@ typedef enum smbc_share_mode
|
||||
} smbc_share_mode;
|
||||
|
||||
|
||||
/**
|
||||
* Values for option SMB Encryption Level, as set and retrieved with
|
||||
* smbc_setOptionSmbEncryptionLevel() and smbc_getOptionSmbEncryptionLevel()
|
||||
*/
|
||||
typedef enum smbc_smb_encrypt_level
|
||||
{
|
||||
SMBC_ENCRYPTLEVEL_NONE = 0,
|
||||
SMBC_ENCRYPTLEVEL_REQUEST = 1,
|
||||
SMBC_ENCRYPTLEVEL_REQUIRE = 2
|
||||
} smbc_smb_encrypt_level;
|
||||
|
||||
|
||||
typedef int smbc_bool;
|
||||
|
||||
|
||||
#ifndef ENOATTR
|
||||
# define ENOATTR ENOENT /* No such attribute */
|
||||
#endif
|
||||
@ -214,11 +229,17 @@ typedef struct _SMBCCTX SMBCCTX;
|
||||
|
||||
|
||||
/*
|
||||
* Flags for SMBCCTX->flags
|
||||
*
|
||||
* NEW CODE SHOULD NOT DIRECTLY MANIPULATE THE CONTEXT STRUCTURE.
|
||||
* For these options, use smbc_option_set() and smbc_option_get().
|
||||
* Instead, use:
|
||||
* smbc_setOptionUseKerberos()
|
||||
* smbc_getOptionUseKerberos()
|
||||
* smbc_setOptionFallbackAfterKerberos()
|
||||
* smbc_getOptionFallbackAFterKerberos()
|
||||
* smbc_setOptionNoAutoAnonymousLogin()
|
||||
* smbc_getOptionNoAutoAnonymousLogin()
|
||||
*/
|
||||
|
||||
/* Flags for SMBCCTX->flags */
|
||||
# define SMB_CTX_FLAG_USE_KERBEROS (1 << 0)
|
||||
# define SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS (1 << 1)
|
||||
# define SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON (1 << 2)
|
||||
@ -398,48 +419,286 @@ typedef int (*smbc_remove_cached_srv_fn)(SMBCCTX * c, SMBCSRV *srv);
|
||||
typedef int (*smbc_purge_cached_srv_fn) (SMBCCTX * c);
|
||||
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Getters and setters for CONFIGURATION *
|
||||
*****************************************/
|
||||
|
||||
/** Get the debug level */
|
||||
int smbc_getDebug(SMBCCTX *c);
|
||||
int
|
||||
smbc_getDebug(SMBCCTX *c);
|
||||
|
||||
/** Set the debug level */
|
||||
void smbc_setDebug(SMBCCTX *c, int debug);
|
||||
void
|
||||
smbc_setDebug(SMBCCTX *c, int debug);
|
||||
|
||||
/** Get the netbios name used for making connections */
|
||||
char * smbc_getNetbiosName(SMBCCTX *c);
|
||||
char *
|
||||
smbc_getNetbiosName(SMBCCTX *c);
|
||||
|
||||
/** Set the netbios name used for making connections */
|
||||
void smbc_setNetbiosName(SMBCCTX *c, char * netbios_name);
|
||||
void
|
||||
smbc_setNetbiosName(SMBCCTX *c, char * netbios_name);
|
||||
|
||||
/** Get the workgroup used for making connections */
|
||||
char * smbc_getWorkgroup(SMBCCTX *c);
|
||||
char *
|
||||
smbc_getWorkgroup(SMBCCTX *c);
|
||||
|
||||
/** Set the workgroup used for making connections */
|
||||
void smbc_setWorkgroup(SMBCCTX *c, char * workgroup);
|
||||
|
||||
/** Get the username used for making connections */
|
||||
char * smbc_getUser(SMBCCTX *c);
|
||||
char *
|
||||
smbc_getUser(SMBCCTX *c);
|
||||
|
||||
/** Set the username used for making connections */
|
||||
void smbc_setUser(SMBCCTX *c, char * user);
|
||||
void
|
||||
smbc_setUser(SMBCCTX *c, char * user);
|
||||
|
||||
/**
|
||||
* Get the timeout used for waiting on connections and response data
|
||||
* (in milliseconds)
|
||||
*/
|
||||
int smbc_getTimeout(SMBCCTX *c);
|
||||
int
|
||||
smbc_getTimeout(SMBCCTX *c);
|
||||
|
||||
/**
|
||||
* Set the timeout used for waiting on connections and response data
|
||||
* (in milliseconds)
|
||||
*/
|
||||
void smbc_setTimeout(SMBCCTX *c, int timeout);
|
||||
void
|
||||
smbc_setTimeout(SMBCCTX *c, int timeout);
|
||||
|
||||
|
||||
|
||||
/***********************************
|
||||
* Getters and setters for OPTIONS *
|
||||
***********************************/
|
||||
|
||||
/** Get whether to log to standard error instead of standard output */
|
||||
smbc_bool
|
||||
smbc_getOptionDebugToStderr(SMBCCTX *c);
|
||||
|
||||
/** Set whether to log to standard error instead of standard output */
|
||||
void
|
||||
smbc_setOptionDebugToStderr(SMBCCTX *c, smbc_bool b);
|
||||
|
||||
/**
|
||||
* Get whether to use new-style time attribute names, e.g. WRITE_TIME rather
|
||||
* than the old-style names such as M_TIME. This allows also setting/getting
|
||||
* CREATE_TIME which was previously unimplemented. (Note that the old C_TIME
|
||||
* was supposed to be CHANGE_TIME but was confused and sometimes referred to
|
||||
* CREATE_TIME.)
|
||||
*/
|
||||
smbc_bool
|
||||
smbc_getOptionFullTimeNames(SMBCCTX *c);
|
||||
|
||||
/**
|
||||
* Set whether to use new-style time attribute names, e.g. WRITE_TIME rather
|
||||
* than the old-style names such as M_TIME. This allows also setting/getting
|
||||
* CREATE_TIME which was previously unimplemented. (Note that the old C_TIME
|
||||
* was supposed to be CHANGE_TIME but was confused and sometimes referred to
|
||||
* CREATE_TIME.)
|
||||
*/
|
||||
void
|
||||
smbc_setOptionFullTimeNames(SMBCCTX *c, smbc_bool b);
|
||||
|
||||
/**
|
||||
* Get the share mode to use for files opened with SMBC_open_ctx(). The
|
||||
* default is SMBC_SHAREMODE_DENY_NONE.
|
||||
*/
|
||||
smbc_share_mode
|
||||
smbc_getOptionOpenShareMode(SMBCCTX *c);
|
||||
|
||||
/**
|
||||
* Set the share mode to use for files opened with SMBC_open_ctx(). The
|
||||
* default is SMBC_SHAREMODE_DENY_NONE.
|
||||
*/
|
||||
void
|
||||
smbc_setOptionOpenShareMode(SMBCCTX *c, smbc_share_mode share_mode);
|
||||
|
||||
/** Retrieve a previously saved user data handle */
|
||||
void *
|
||||
smbc_getOptionUserData(SMBCCTX *c);
|
||||
|
||||
/** Save a user data handle */
|
||||
void
|
||||
smbc_setOptionUserData(SMBCCTX *c, void *user_data);
|
||||
|
||||
/** Get the encoded value for encryption level. */
|
||||
smbc_smb_encrypt_level
|
||||
smbc_getOptionSmbEncryptionLevel(SMBCCTX *c);
|
||||
|
||||
/** Set the encoded value for encryption level. */
|
||||
void
|
||||
smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level);
|
||||
|
||||
/**
|
||||
* Get from how many local master browsers should the list of workgroups be
|
||||
* retrieved. It can take up to 12 minutes or longer after a server becomes a
|
||||
* local master browser, for it to have the entire browse list (the list of
|
||||
* workgroups/domains) from an entire network. Since a client never knows
|
||||
* which local master browser will be found first, the one which is found
|
||||
* first and used to retrieve a browse list may have an incomplete or empty
|
||||
* browse list. By requesting the browse list from multiple local master
|
||||
* browsers, a more complete list can be generated. For small networks (few
|
||||
* workgroups), it is recommended that this value be set to 0, causing the
|
||||
* browse lists from all found local master browsers to be retrieved and
|
||||
* merged. For networks with many workgroups, a suitable value for this
|
||||
* variable is probably somewhere around 3. (Default: 3).
|
||||
*/
|
||||
int
|
||||
smbc_getOptionBrowseMaxLmbCount(SMBCCTX *c);
|
||||
|
||||
/**
|
||||
* Set from how many local master browsers should the list of workgroups be
|
||||
* retrieved. It can take up to 12 minutes or longer after a server becomes a
|
||||
* local master browser, for it to have the entire browse list (the list of
|
||||
* workgroups/domains) from an entire network. Since a client never knows
|
||||
* which local master browser will be found first, the one which is found
|
||||
* first and used to retrieve a browse list may have an incomplete or empty
|
||||
* browse list. By requesting the browse list from multiple local master
|
||||
* browsers, a more complete list can be generated. For small networks (few
|
||||
* workgroups), it is recommended that this value be set to 0, causing the
|
||||
* browse lists from all found local master browsers to be retrieved and
|
||||
* merged. For networks with many workgroups, a suitable value for this
|
||||
* variable is probably somewhere around 3. (Default: 3).
|
||||
*/
|
||||
void
|
||||
smbc_setOptionBrowseMaxLmbCount(SMBCCTX *c, int count);
|
||||
|
||||
/**
|
||||
* Get whether to url-encode readdir entries.
|
||||
*
|
||||
* There is a difference in the desired return strings from
|
||||
* smbc_readdir() depending upon whether the filenames are to
|
||||
* be displayed to the user, or whether they are to be
|
||||
* appended to the path name passed to smbc_opendir() to call
|
||||
* a further smbc_ function (e.g. open the file with
|
||||
* smbc_open()). In the former case, the filename should be
|
||||
* in "human readable" form. In the latter case, the smbc_
|
||||
* functions expect a URL which must be url-encoded. Those
|
||||
* functions decode the URL. If, for example, smbc_readdir()
|
||||
* returned a file name of "abc%20def.txt", passing a path
|
||||
* with this file name attached to smbc_open() would cause
|
||||
* smbc_open to attempt to open the file "abc def.txt" since
|
||||
* the %20 is decoded into a space.
|
||||
*
|
||||
* Set this option to True if the names returned by
|
||||
* smbc_readdir() should be url-encoded such that they can be
|
||||
* passed back to another smbc_ call. Set it to False if the
|
||||
* names returned by smbc_readdir() are to be presented to the
|
||||
* user.
|
||||
*
|
||||
* For backwards compatibility, this option defaults to False.
|
||||
*/
|
||||
smbc_bool
|
||||
smbc_getOptionUrlEncodeReaddirEntries(SMBCCTX *c);
|
||||
|
||||
/**
|
||||
* Set whether to url-encode readdir entries.
|
||||
*
|
||||
* There is a difference in the desired return strings from
|
||||
* smbc_readdir() depending upon whether the filenames are to
|
||||
* be displayed to the user, or whether they are to be
|
||||
* appended to the path name passed to smbc_opendir() to call
|
||||
* a further smbc_ function (e.g. open the file with
|
||||
* smbc_open()). In the former case, the filename should be
|
||||
* in "human readable" form. In the latter case, the smbc_
|
||||
* functions expect a URL which must be url-encoded. Those
|
||||
* functions decode the URL. If, for example, smbc_readdir()
|
||||
* returned a file name of "abc%20def.txt", passing a path
|
||||
* with this file name attached to smbc_open() would cause
|
||||
* smbc_open to attempt to open the file "abc def.txt" since
|
||||
* the %20 is decoded into a space.
|
||||
*
|
||||
* Set this option to True if the names returned by
|
||||
* smbc_readdir() should be url-encoded such that they can be
|
||||
* passed back to another smbc_ call. Set it to False if the
|
||||
* names returned by smbc_readdir() are to be presented to the
|
||||
* user.
|
||||
*
|
||||
* For backwards compatibility, this option defaults to False.
|
||||
*/
|
||||
void
|
||||
smbc_setOptionUrlEncodeReaddirEntries(SMBCCTX *c, smbc_bool b);
|
||||
|
||||
/**
|
||||
* Get whether to use the same connection for all shares on a server.
|
||||
*
|
||||
* Some Windows versions appear to have a limit to the number
|
||||
* of concurrent SESSIONs and/or TREE CONNECTions. In
|
||||
* one-shot programs (i.e. the program runs and then quickly
|
||||
* ends, thereby shutting down all connections), it is
|
||||
* probably reasonable to establish a new connection for each
|
||||
* share. In long-running applications, the limitation can be
|
||||
* avoided by using only a single connection to each server,
|
||||
* and issuing a new TREE CONNECT when the share is accessed.
|
||||
*/
|
||||
smbc_bool
|
||||
smbc_getOptionOneSharePerServer(SMBCCTX *c);
|
||||
|
||||
/**
|
||||
* Set whether to use the same connection for all shares on a server.
|
||||
*
|
||||
* Some Windows versions appear to have a limit to the number
|
||||
* of concurrent SESSIONs and/or TREE CONNECTions. In
|
||||
* one-shot programs (i.e. the program runs and then quickly
|
||||
* ends, thereby shutting down all connections), it is
|
||||
* probably reasonable to establish a new connection for each
|
||||
* share. In long-running applications, the limitation can be
|
||||
* avoided by using only a single connection to each server,
|
||||
* and issuing a new TREE CONNECT when the share is accessed.
|
||||
*/
|
||||
void
|
||||
smbc_setOptionOneSharePerServer(SMBCCTX *c, smbc_bool b);
|
||||
|
||||
/** Get whether to enable use of kerberos */
|
||||
smbc_bool
|
||||
smbc_getOptionUseKerberos(SMBCCTX *c);
|
||||
|
||||
/** Set whether to enable use of kerberos */
|
||||
void
|
||||
smbc_setOptionUseKerberos(SMBCCTX *c, smbc_bool b);
|
||||
|
||||
/** Get whether to fallback after kerberos */
|
||||
smbc_bool
|
||||
smbc_getOptionFallbackAfterKerberos(SMBCCTX *c);
|
||||
|
||||
/** Set whether to fallback after kerberos */
|
||||
void
|
||||
smbc_setOptionFallbackAfterKerberos(SMBCCTX *c, smbc_bool b);
|
||||
|
||||
/** Get whether to automatically select anonymous login */
|
||||
smbc_bool
|
||||
smbc_getOptionNoAutoAnonymousLogin(SMBCCTX *c);
|
||||
|
||||
/** Set whether to automatically select anonymous login */
|
||||
void
|
||||
smbc_setOptionNoAutoAnonymousLogin(SMBCCTX *c, smbc_bool b);
|
||||
|
||||
/** Get the function for obtaining authentication data */
|
||||
smbc_get_auth_data_fn smbc_getFunctionAuthData(SMBCCTX *c);
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
* Getters and setters for FUNCTIONS *
|
||||
*************************************/
|
||||
|
||||
/** Set the function for obtaining authentication data */
|
||||
void smbc_setFunctionAuthData(SMBCCTX *c, smbc_get_auth_data_fn f);
|
||||
|
||||
/** Get the new-style authentication function which includes the context. */
|
||||
smbc_get_auth_data_with_context_fn
|
||||
smbc_getFunctionAuthDataWithContext(SMBCCTX *c);
|
||||
|
||||
/** Set the new-style authentication function which includes the context. */
|
||||
void
|
||||
smbc_setFunctionAuthDataWithContext(SMBCCTX *c,
|
||||
smbc_get_auth_data_with_context_fn fn);
|
||||
|
||||
/** Get the function for checking if a server is still good */
|
||||
smbc_check_server_fn smbc_getFunctionCheckServer(SMBCCTX *c);
|
||||
|
||||
@ -492,9 +751,12 @@ struct smbc_server_cache * smbc_getServerCacheData(SMBCCTX *c);
|
||||
void smbc_setServerCacheData(SMBCCTX *c, struct smbc_server_cache * cache);
|
||||
|
||||
|
||||
/**
|
||||
* Callable functions for files.
|
||||
*/
|
||||
|
||||
/*****************************************************************
|
||||
* Callable functions for files. *
|
||||
* Each callable has a function signature typedef, a declaration *
|
||||
* for the getter, and a declaration for the setter. *
|
||||
*****************************************************************/
|
||||
|
||||
typedef SMBCFILE * (*smbc_open_fn)(SMBCCTX *c,
|
||||
const char *fname,
|
||||
@ -566,9 +828,12 @@ smbc_close_fn smbc_getFunctionClose(SMBCCTX *c);
|
||||
void smbc_setFunctionClose(SMBCCTX *c, smbc_close_fn f);
|
||||
|
||||
|
||||
/**
|
||||
* Callable functions for directories.
|
||||
*/
|
||||
|
||||
/*****************************************************************
|
||||
* Callable functions for directories. *
|
||||
* Each callable has a function signature typedef, a declaration *
|
||||
* for the getter, and a declaration for the setter. *
|
||||
*****************************************************************/
|
||||
|
||||
typedef SMBCFILE * (*smbc_opendir_fn)(SMBCCTX *c,
|
||||
const char *fname);
|
||||
@ -621,9 +886,12 @@ smbc_fstatdir_fn smbc_getFunctionFstatdir(SMBCCTX *c);
|
||||
void smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn f);
|
||||
|
||||
|
||||
/**
|
||||
* Callable functions applicable to both files and directories.
|
||||
*/
|
||||
|
||||
/*****************************************************************
|
||||
* Callable functions applicable to both files and directories. *
|
||||
* Each callable has a function signature typedef, a declaration *
|
||||
* for the getter, and a declaration for the setter. *
|
||||
*****************************************************************/
|
||||
|
||||
typedef int (*smbc_chmod_fn)(SMBCCTX *c,
|
||||
const char *fname,
|
||||
@ -668,9 +936,12 @@ smbc_listxattr_fn smbc_getFunctionListxattr(SMBCCTX *c);
|
||||
void smbc_setFunctionListxattr(SMBCCTX *c, smbc_listxattr_fn f);
|
||||
|
||||
|
||||
/**
|
||||
* Callable functions related to printing
|
||||
*/
|
||||
|
||||
/*****************************************************************
|
||||
* Callable functions for printing. *
|
||||
* Each callable has a function signature typedef, a declaration *
|
||||
* for the getter, and a declaration for the setter. *
|
||||
*****************************************************************/
|
||||
|
||||
typedef int (*smbc_print_file_fn)(SMBCCTX *c_file,
|
||||
const char *fname,
|
||||
@ -2341,6 +2612,7 @@ struct _SMBCCTX {
|
||||
/**
|
||||
* debug level
|
||||
*
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use smbc_getDebug() and smbc_setDebug()
|
||||
*/
|
||||
int debug;
|
||||
@ -2348,6 +2620,7 @@ struct _SMBCCTX {
|
||||
/**
|
||||
* netbios name used for making connections
|
||||
*
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use smbc_getNetbiosName() and smbc_setNetbiosName()
|
||||
*/
|
||||
char * netbios_name;
|
||||
@ -2355,6 +2628,7 @@ struct _SMBCCTX {
|
||||
/**
|
||||
* workgroup name used for making connections
|
||||
*
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use smbc_getWorkgroup() and smbc_setWorkgroup()
|
||||
*/
|
||||
char * workgroup;
|
||||
@ -2362,6 +2636,7 @@ struct _SMBCCTX {
|
||||
/**
|
||||
* username used for making connections
|
||||
*
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use smbc_getUser() and smbc_setUser()
|
||||
*/
|
||||
char * user;
|
||||
@ -2370,6 +2645,7 @@ struct _SMBCCTX {
|
||||
* timeout used for waiting on connections / response data (in
|
||||
* milliseconds)
|
||||
*
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use smbc_getTimeout() and smbc_setTimeout()
|
||||
*/
|
||||
int timeout;
|
||||
@ -2379,6 +2655,8 @@ struct _SMBCCTX {
|
||||
* callable functions for files:
|
||||
* For usage and return values see the SMBC_* functions
|
||||
*
|
||||
* Manually setting/retrieving these values is deprecated.
|
||||
*
|
||||
* Use smbc_getFunction*() and smbc_setFunction*(), e.g.
|
||||
* smbc_getFunctionOpen(), smbc_setFunctionUnlink(), etc.
|
||||
*/
|
||||
@ -2433,6 +2711,7 @@ struct _SMBCCTX {
|
||||
/**
|
||||
* authentication function callback: called upon auth requests
|
||||
*
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use smbc_getFunctionAuthData(), smbc_setFunctionAuthData()
|
||||
*/
|
||||
smbc_get_auth_data_fn get_auth_data_fn;
|
||||
@ -2440,6 +2719,7 @@ struct _SMBCCTX {
|
||||
/**
|
||||
* check if a server is still good
|
||||
*
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use smbc_getFunctionCheckServer(),
|
||||
* smbc_setFunctionCheckServer()
|
||||
*/
|
||||
@ -2448,6 +2728,7 @@ struct _SMBCCTX {
|
||||
/**
|
||||
* remove a server if unused
|
||||
*
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use smbc_getFunctionRemoveUnusedServer(),
|
||||
* smbc_setFunctionCheckServer()
|
||||
*/
|
||||
@ -2467,6 +2748,7 @@ struct _SMBCCTX {
|
||||
/**
|
||||
* server cache addition
|
||||
*
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use smbc_getFunctionAddCachedServer(),
|
||||
* smbc_setFunctionAddCachedServer()
|
||||
*/
|
||||
@ -2475,6 +2757,7 @@ struct _SMBCCTX {
|
||||
/**
|
||||
* server cache lookup
|
||||
*
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use smbc_getFunctionGetCachedServer(),
|
||||
* smbc_setFunctionGetCachedServer()
|
||||
*/
|
||||
@ -2483,6 +2766,7 @@ struct _SMBCCTX {
|
||||
/**
|
||||
* server cache removal
|
||||
*
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use smbc_getFunctionRemoveCachedServer(),
|
||||
* smbc_setFunctionRemoveCachedServer()
|
||||
*/
|
||||
@ -2492,6 +2776,7 @@ struct _SMBCCTX {
|
||||
* server cache purging, try to remove all cached servers
|
||||
* (disconnect)
|
||||
*
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use smbc_getFunctionPurgeCachedServers(),
|
||||
* smbc_setFunctionPurgeCachedServers()
|
||||
*/
|
||||
@ -2500,6 +2785,7 @@ struct _SMBCCTX {
|
||||
/**
|
||||
* Space to store private data of the server cache.
|
||||
*
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use smbc_getServerCacheData(), smbc_setServerCacheData()
|
||||
*/
|
||||
struct smbc_server_cache * server_cache_data;
|
||||
@ -2508,7 +2794,14 @@ struct _SMBCCTX {
|
||||
/*
|
||||
* Very old configuration options.
|
||||
*
|
||||
* Use smbc_option_set() and smbc_option_get() instead.
|
||||
* Manually setting/retrieving this value is deprecated.
|
||||
* Use one of the following functions instead:
|
||||
* smbc_setOptionUseKerberos()
|
||||
* smbc_getOptionUseKerberos()
|
||||
* smbc_setOptionFallbackAfterKerberos()
|
||||
* smbc_getOptionFallbackAfterKerberos()
|
||||
* smbc_setOptionNoAutoAnonymousLogin()
|
||||
* smbc_getOptionNoAutoAnonymousLogin()
|
||||
*/
|
||||
struct
|
||||
{
|
||||
@ -2521,66 +2814,12 @@ struct _SMBCCTX {
|
||||
*
|
||||
* NEW OPTIONS ARE NOT ADDED HERE!
|
||||
*
|
||||
* We must maintain ABI backward compatibility. We now use
|
||||
* smbc_option_set() and smbc_option_get() for all newly added
|
||||
* options.
|
||||
* To set and retrieve options, use the smbc_setOption*() and
|
||||
* smbc_getOption*() functions.
|
||||
*/
|
||||
struct _smbc_options {
|
||||
|
||||
/*
|
||||
* From how many local master browsers should the list of
|
||||
* workgroups be retrieved? It can take up to 12 minutes or
|
||||
* longer after a server becomes a local master browser, for
|
||||
* it to have the entire browse list (the list of
|
||||
* workgroups/domains) from an entire network. Since a client
|
||||
* never knows which local master browser will be found first,
|
||||
* the one which is found first and used to retrieve a browse
|
||||
* list may have an incomplete or empty browse list. By
|
||||
* requesting the browse list from multiple local master
|
||||
* browsers, a more complete list can be generated. For small
|
||||
* networks (few workgroups), it is recommended that this
|
||||
* value be set to 0, causing the browse lists from all found
|
||||
* local master browsers to be retrieved and merged. For
|
||||
* networks with many workgroups, a suitable value for this
|
||||
* variable is probably somewhere around 3. (Default: 3).
|
||||
*/
|
||||
int browse_max_lmb_count;
|
||||
|
||||
/*
|
||||
* There is a difference in the desired return strings from
|
||||
* smbc_readdir() depending upon whether the filenames are to
|
||||
* be displayed to the user, or whether they are to be
|
||||
* appended to the path name passed to smbc_opendir() to call
|
||||
* a further smbc_ function (e.g. open the file with
|
||||
* smbc_open()). In the former case, the filename should be
|
||||
* in "human readable" form. In the latter case, the smbc_
|
||||
* functions expect a URL which must be url-encoded. Those
|
||||
* functions decode the URL. If, for example, smbc_readdir()
|
||||
* returned a file name of "abc%20def.txt", passing a path
|
||||
* with this file name attached to smbc_open() would cause
|
||||
* smbc_open to attempt to open the file "abc def.txt" since
|
||||
* the %20 is decoded into a space.
|
||||
*
|
||||
* Set this option to True if the names returned by
|
||||
* smbc_readdir() should be url-encoded such that they can be
|
||||
* passed back to another smbc_ call. Set it to False if the
|
||||
* names returned by smbc_readdir() are to be presented to the
|
||||
* user.
|
||||
*
|
||||
* For backwards compatibility, this option defaults to False.
|
||||
*/
|
||||
int urlencode_readdir_entries;
|
||||
|
||||
/*
|
||||
* Some Windows versions appear to have a limit to the number
|
||||
* of concurrent SESSIONs and/or TREE CONNECTions. In
|
||||
* one-shot programs (i.e. the program runs and then quickly
|
||||
* ends, thereby shutting down all connections), it is
|
||||
* probably reasonable to establish a new connection for each
|
||||
* share. In long-running applications, the limitation can be
|
||||
* avoided by using only a single connection to each server,
|
||||
* and issuing a new TREE CONNECT when the share is accessed.
|
||||
*/
|
||||
int one_share_per_server;
|
||||
} options;
|
||||
|
||||
|
@ -35,10 +35,10 @@ struct smbc_server_cache {
|
||||
char *workgroup;
|
||||
char *username;
|
||||
SMBCSRV *server;
|
||||
|
||||
|
||||
struct smbc_server_cache *next, *prev;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@ -54,51 +54,51 @@ SMBC_add_cached_server(SMBCCTX * context,
|
||||
const char * username)
|
||||
{
|
||||
struct smbc_server_cache * srvcache = NULL;
|
||||
|
||||
|
||||
if (!(srvcache = SMB_MALLOC_P(struct smbc_server_cache))) {
|
||||
errno = ENOMEM;
|
||||
DEBUG(3, ("Not enough space for server cache allocation\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
ZERO_STRUCTP(srvcache);
|
||||
|
||||
|
||||
srvcache->server = newsrv;
|
||||
|
||||
|
||||
srvcache->server_name = SMB_STRDUP(server);
|
||||
if (!srvcache->server_name) {
|
||||
errno = ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
srvcache->share_name = SMB_STRDUP(share);
|
||||
if (!srvcache->share_name) {
|
||||
errno = ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
srvcache->workgroup = SMB_STRDUP(workgroup);
|
||||
if (!srvcache->workgroup) {
|
||||
errno = ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
srvcache->username = SMB_STRDUP(username);
|
||||
if (!srvcache->username) {
|
||||
errno = ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
DLIST_ADD((context->cache.server_cache_data), srvcache);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
||||
failed:
|
||||
SAFE_FREE(srvcache->server_name);
|
||||
SAFE_FREE(srvcache->share_name);
|
||||
SAFE_FREE(srvcache->workgroup);
|
||||
SAFE_FREE(srvcache->username);
|
||||
SAFE_FREE(srvcache);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -117,19 +117,19 @@ SMBC_get_cached_server(SMBCCTX * context,
|
||||
const char * user)
|
||||
{
|
||||
struct smbc_server_cache * srv = NULL;
|
||||
|
||||
|
||||
/* Search the cache lines */
|
||||
for (srv = context->cache.server_cache_data; srv; srv = srv->next) {
|
||||
|
||||
|
||||
if (strcmp(server,srv->server_name) == 0 &&
|
||||
strcmp(workgroup,srv->workgroup) == 0 &&
|
||||
strcmp(user, srv->username) == 0) {
|
||||
|
||||
|
||||
/* If the share name matches, we're cool */
|
||||
if (strcmp(share, srv->share_name) == 0) {
|
||||
return srv->server;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We only return an empty share name or the attribute
|
||||
* server on an exact match (which would have been
|
||||
@ -137,7 +137,7 @@ SMBC_get_cached_server(SMBCCTX * context,
|
||||
*/
|
||||
if (*share == '\0' || strcmp(share, "*IPC$") == 0)
|
||||
continue;
|
||||
|
||||
|
||||
/*
|
||||
* Never return an empty share name or the attribute
|
||||
* server if it wasn't what was requested.
|
||||
@ -145,7 +145,7 @@ SMBC_get_cached_server(SMBCCTX * context,
|
||||
if (*srv->share_name == '\0' ||
|
||||
strcmp(srv->share_name, "*IPC$") == 0)
|
||||
continue;
|
||||
|
||||
|
||||
/*
|
||||
* If we're only allowing one share per server, then
|
||||
* a connection to the server (other than the
|
||||
@ -164,7 +164,7 @@ SMBC_get_cached_server(SMBCCTX * context,
|
||||
context->cache.remove_cached_server_fn(context, srv->server);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Save the new share name. We've
|
||||
* disconnected from the old share, and are
|
||||
@ -179,13 +179,13 @@ SMBC_get_cached_server(SMBCCTX * context,
|
||||
context->cache.remove_cached_server_fn(context, srv->server);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return srv->server;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -200,10 +200,10 @@ SMBC_remove_cached_server(SMBCCTX * context,
|
||||
SMBCSRV * server)
|
||||
{
|
||||
struct smbc_server_cache * srv = NULL;
|
||||
|
||||
|
||||
for (srv = context->cache.server_cache_data; srv; srv = srv->next) {
|
||||
if (server == srv->server) {
|
||||
|
||||
|
||||
/* remove this sucker */
|
||||
DLIST_REMOVE(context->cache.server_cache_data, srv);
|
||||
SAFE_FREE(srv->server_name);
|
||||
@ -229,13 +229,13 @@ SMBC_purge_cached_servers(SMBCCTX * context)
|
||||
struct smbc_server_cache * srv;
|
||||
struct smbc_server_cache * next;
|
||||
int could_not_purge_all = 0;
|
||||
|
||||
|
||||
for (srv = context->cache.server_cache_data,
|
||||
next = (srv ? srv->next :NULL);
|
||||
srv;
|
||||
srv = next,
|
||||
next = (srv ? srv->next : NULL)) {
|
||||
|
||||
|
||||
if (SMBC_remove_unused_server(context, srv->server)) {
|
||||
/* could not be removed */
|
||||
could_not_purge_all = 1;
|
||||
|
@ -55,11 +55,11 @@ static int
|
||||
add_fd(SMBCFILE * file)
|
||||
{
|
||||
struct smbc_compat_fdlist * f = smbc_compat_fd_avail;
|
||||
|
||||
|
||||
if (f) {
|
||||
/* We found one that's available */
|
||||
DLIST_REMOVE(smbc_compat_fd_avail, f);
|
||||
|
||||
|
||||
} else {
|
||||
/*
|
||||
* None were available, so allocate one. Keep the number of
|
||||
@ -72,19 +72,19 @@ add_fd(SMBCFILE * file)
|
||||
errno = EMFILE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
f = SMB_MALLOC_P(struct smbc_compat_fdlist);
|
||||
if (!f) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
f->fd = SMBC_BASE_FD + smbc_compat_nextfd++;
|
||||
}
|
||||
|
||||
|
||||
f->file = file;
|
||||
DLIST_ADD(smbc_compat_fd_in_use, f);
|
||||
|
||||
|
||||
return f->fd;
|
||||
}
|
||||
|
||||
@ -95,13 +95,13 @@ static int
|
||||
del_fd(int fd)
|
||||
{
|
||||
struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
|
||||
|
||||
|
||||
while (f) {
|
||||
if (f->fd == fd)
|
||||
break;
|
||||
f = f->next;
|
||||
}
|
||||
|
||||
|
||||
if (f) {
|
||||
/* found */
|
||||
DLIST_REMOVE(smbc_compat_fd_in_use, f);
|
||||
@ -111,7 +111,7 @@ del_fd(int fd)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
@ -122,17 +122,17 @@ smbc_init(smbc_get_auth_data_fn fn,
|
||||
statcont = smbc_new_context();
|
||||
if (!statcont)
|
||||
return -1;
|
||||
|
||||
|
||||
smbc_setDebug(statcont, debug);
|
||||
smbc_setFunctionAuthData(statcont, fn);
|
||||
|
||||
|
||||
if (!smbc_init_context(statcont)) {
|
||||
smbc_free_context(statcont, False);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
smbc_compat_initialized = 1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
@ -143,11 +143,11 @@ SMBCCTX *
|
||||
smbc_set_context(SMBCCTX * context)
|
||||
{
|
||||
SMBCCTX *old_context = statcont;
|
||||
|
||||
|
||||
if (context) {
|
||||
/* Save provided context. It must have been initialized! */
|
||||
statcont = context;
|
||||
|
||||
|
||||
/* You'd better know what you're doing. We won't help you. */
|
||||
smbc_compat_initialized = 1;
|
||||
}
|
||||
@ -163,11 +163,11 @@ smbc_open(const char *furl,
|
||||
{
|
||||
SMBCFILE * file;
|
||||
int fd;
|
||||
|
||||
|
||||
file = smbc_getFunctionOpen(statcont)(statcont, furl, flags, mode);
|
||||
if (!file)
|
||||
return -1;
|
||||
|
||||
|
||||
fd = add_fd(file);
|
||||
if (fd == -1)
|
||||
smbc_getFunctionClose(statcont)(statcont, file);
|
||||
@ -181,11 +181,11 @@ smbc_creat(const char *furl,
|
||||
{
|
||||
SMBCFILE * file;
|
||||
int fd;
|
||||
|
||||
|
||||
file = smbc_getFunctionCreat(statcont)(statcont, furl, mode);
|
||||
if (!file)
|
||||
return -1;
|
||||
|
||||
|
||||
fd = add_fd(file);
|
||||
if (fd == -1) {
|
||||
/* Hmm... should we delete the file too ? I guess we could try */
|
||||
@ -250,15 +250,15 @@ smbc_opendir(const char *durl)
|
||||
{
|
||||
SMBCFILE * file;
|
||||
int fd;
|
||||
|
||||
|
||||
file = smbc_getFunctionOpendir(statcont)(statcont, durl);
|
||||
if (!file)
|
||||
return -1;
|
||||
|
||||
|
||||
fd = add_fd(file);
|
||||
if (fd == -1)
|
||||
smbc_getFunctionClosedir(statcont)(statcont, file);
|
||||
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
@ -357,14 +357,14 @@ smbc_utime(const char *fname,
|
||||
struct utimbuf *utbuf)
|
||||
{
|
||||
struct timeval tv[2];
|
||||
|
||||
|
||||
if (utbuf == NULL)
|
||||
return smbc_getFunctionUtimes(statcont)(statcont, fname, NULL);
|
||||
|
||||
|
||||
tv[0].tv_sec = utbuf->actime;
|
||||
tv[1].tv_sec = utbuf->modtime;
|
||||
tv[0].tv_usec = tv[1].tv_usec = 0;
|
||||
|
||||
|
||||
return smbc_getFunctionUtimes(statcont)(statcont, fname, tv);
|
||||
}
|
||||
#endif
|
||||
@ -519,7 +519,7 @@ int
|
||||
smbc_open_print_job(const char *fname)
|
||||
{
|
||||
SMBCFILE * file;
|
||||
|
||||
|
||||
file = smbc_getFunctionOpenPrintJob(statcont)(statcont, fname);
|
||||
if (!file) return -1;
|
||||
return file->cli_fd;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,11 @@ SMBC_open_ctx(SMBCCTX *context,
|
||||
int flags,
|
||||
mode_t mode)
|
||||
{
|
||||
char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL;
|
||||
char *server = NULL;
|
||||
char *share = NULL;
|
||||
char *user = NULL;
|
||||
char *password = NULL;
|
||||
char *workgroup = NULL;
|
||||
char *path = NULL;
|
||||
char *targetpath = NULL;
|
||||
struct cli_state *targetcli = NULL;
|
||||
@ -45,38 +49,38 @@ SMBC_open_ctx(SMBCCTX *context,
|
||||
SMBCFILE *file = NULL;
|
||||
int fd;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL; /* Best I can think of ... */
|
||||
TALLOC_FREE(frame);
|
||||
return NULL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!fname) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return NULL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (SMBC_parse_path(frame,
|
||||
context,
|
||||
fname,
|
||||
&workgroup,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
context,
|
||||
fname,
|
||||
&workgroup,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (!user || user[0] == (char)0) {
|
||||
user = talloc_strdup(frame, context->config.user);
|
||||
if (!user) {
|
||||
@ -85,62 +89,63 @@ SMBC_open_ctx(SMBCCTX *context,
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
srv = SMBC_server(frame, context, True,
|
||||
server, share, &workgroup, &user, &password);
|
||||
|
||||
|
||||
if (!srv) {
|
||||
if (errno == EPERM) errno = EACCES;
|
||||
TALLOC_FREE(frame);
|
||||
return NULL; /* SMBC_server sets errno */
|
||||
}
|
||||
|
||||
|
||||
/* Hmmm, the test for a directory is suspect here ... FIXME */
|
||||
|
||||
|
||||
if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') {
|
||||
fd = -1;
|
||||
} else {
|
||||
file = SMB_MALLOC_P(SMBCFILE);
|
||||
|
||||
|
||||
if (!file) {
|
||||
errno = ENOMEM;
|
||||
TALLOC_FREE(frame);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ZERO_STRUCTP(file);
|
||||
|
||||
|
||||
/*d_printf(">>>open: resolving %s\n", path);*/
|
||||
if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) {
|
||||
if (!cli_resolve_path(frame, "", srv->cli, path,
|
||||
&targetcli, &targetpath)) {
|
||||
d_printf("Could not resolve %s\n", path);
|
||||
SAFE_FREE(file);
|
||||
TALLOC_FREE(frame);
|
||||
return NULL;
|
||||
}
|
||||
/*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/
|
||||
|
||||
|
||||
if ((fd = cli_open(targetcli, targetpath, flags,
|
||||
context->internal->share_mode)) < 0) {
|
||||
|
||||
|
||||
/* Handle the error ... */
|
||||
|
||||
|
||||
SAFE_FREE(file);
|
||||
errno = SMBC_errno(context, targetcli);
|
||||
TALLOC_FREE(frame);
|
||||
return NULL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Fill in file struct */
|
||||
|
||||
|
||||
file->cli_fd = fd;
|
||||
file->fname = SMB_STRDUP(fname);
|
||||
file->srv = srv;
|
||||
file->offset = 0;
|
||||
file->file = True;
|
||||
|
||||
|
||||
DLIST_ADD(context->internal->files, file);
|
||||
|
||||
|
||||
/*
|
||||
* If the file was opened in O_APPEND mode, all write
|
||||
* operations should be appended to the file. To do that,
|
||||
@ -171,51 +176,50 @@ SMBC_open_ctx(SMBCCTX *context,
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return file;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Check if opendir needed ... */
|
||||
|
||||
|
||||
if (fd == -1) {
|
||||
int eno = 0;
|
||||
|
||||
|
||||
eno = SMBC_errno(context, srv->cli);
|
||||
file = (context->posix_emu.opendir_fn)(context, fname);
|
||||
if (!file) errno = eno;
|
||||
TALLOC_FREE(frame);
|
||||
return file;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
errno = EINVAL; /* FIXME, correct errno ? */
|
||||
TALLOC_FREE(frame);
|
||||
return NULL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine to create a file
|
||||
*/
|
||||
|
||||
static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */
|
||||
|
||||
SMBCFILE *
|
||||
SMBC_creat_ctx(SMBCCTX *context,
|
||||
const char *path,
|
||||
mode_t mode)
|
||||
{
|
||||
|
||||
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
return SMBC_open_ctx(context, path, creat_bits, mode);
|
||||
|
||||
return SMBC_open_ctx(context, path,
|
||||
O_WRONLY | O_CREAT | O_TRUNC, mode);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -234,7 +238,7 @@ SMBC_read_ctx(SMBCCTX *context,
|
||||
char *targetpath = NULL;
|
||||
struct cli_state *targetcli = NULL;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
/*
|
||||
* offset:
|
||||
*
|
||||
@ -245,51 +249,51 @@ SMBC_read_ctx(SMBCCTX *context,
|
||||
* retrieving data at an offset greater than 4GB.
|
||||
*/
|
||||
off_t offset;
|
||||
|
||||
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count));
|
||||
|
||||
|
||||
if (!file || !SMBC_dlist_contains(context->internal->files, file)) {
|
||||
errno = EBADF;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
offset = file->offset;
|
||||
|
||||
|
||||
/* Check that the buffer exists ... */
|
||||
|
||||
|
||||
if (buf == NULL) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*d_printf(">>>read: parsing %s\n", file->fname);*/
|
||||
if (SMBC_parse_path(frame,
|
||||
context,
|
||||
file->fname,
|
||||
NULL,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
context,
|
||||
file->fname,
|
||||
NULL,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*d_printf(">>>read: resolving %s\n", path);*/
|
||||
if (!cli_resolve_path(frame, "", file->srv->cli, path,
|
||||
&targetcli, &targetpath)) {
|
||||
@ -298,24 +302,24 @@ SMBC_read_ctx(SMBCCTX *context,
|
||||
return -1;
|
||||
}
|
||||
/*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/
|
||||
|
||||
|
||||
ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count);
|
||||
|
||||
|
||||
if (ret < 0) {
|
||||
|
||||
|
||||
errno = SMBC_errno(context, targetcli);
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
file->offset += ret;
|
||||
|
||||
|
||||
DEBUG(4, (" --> %d\n", ret));
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return ret; /* Success, ret bytes of data ... */
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -335,50 +339,50 @@ SMBC_write_ctx(SMBCCTX *context,
|
||||
char *targetpath = NULL;
|
||||
struct cli_state *targetcli = NULL;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
/* First check all pointers before dereferencing them */
|
||||
|
||||
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!file || !SMBC_dlist_contains(context->internal->files, file)) {
|
||||
errno = EBADF;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Check that the buffer exists ... */
|
||||
|
||||
|
||||
if (buf == NULL) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
offset = file->offset; /* See "offset" comment in SMBC_read_ctx() */
|
||||
|
||||
|
||||
/*d_printf(">>>write: parsing %s\n", file->fname);*/
|
||||
if (SMBC_parse_path(frame,
|
||||
context,
|
||||
file->fname,
|
||||
NULL,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
context,
|
||||
file->fname,
|
||||
NULL,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*d_printf(">>>write: resolving %s\n", path);*/
|
||||
if (!cli_resolve_path(frame, "", file->srv->cli, path,
|
||||
&targetcli, &targetpath)) {
|
||||
@ -387,18 +391,19 @@ SMBC_write_ctx(SMBCCTX *context,
|
||||
return -1;
|
||||
}
|
||||
/*d_printf(">>>write: resolved path as %s\n", targetpath);*/
|
||||
|
||||
ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count);
|
||||
|
||||
|
||||
ret = cli_write(targetcli, file->cli_fd,
|
||||
0, (char *)buf, offset, count);
|
||||
|
||||
if (ret <= 0) {
|
||||
errno = SMBC_errno(context, targetcli);
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
file->offset += ret;
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return ret; /* Success, 0 bytes of data ... */
|
||||
}
|
||||
@ -417,42 +422,42 @@ SMBC_close_ctx(SMBCCTX *context,
|
||||
char *targetpath = NULL;
|
||||
struct cli_state *targetcli = NULL;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!file || !SMBC_dlist_contains(context->internal->files, file)) {
|
||||
errno = EBADF;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* IS a dir ... */
|
||||
if (!file->file) {
|
||||
TALLOC_FREE(frame);
|
||||
return (context->posix_emu.closedir_fn)(context, file);
|
||||
}
|
||||
|
||||
|
||||
/*d_printf(">>>close: parsing %s\n", file->fname);*/
|
||||
if (SMBC_parse_path(frame,
|
||||
context,
|
||||
file->fname,
|
||||
NULL,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
context,
|
||||
file->fname,
|
||||
NULL,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*d_printf(">>>close: resolving %s\n", path);*/
|
||||
if (!cli_resolve_path(frame, "", file->srv->cli, path,
|
||||
&targetcli, &targetpath)) {
|
||||
@ -461,9 +466,9 @@ SMBC_close_ctx(SMBCCTX *context,
|
||||
return -1;
|
||||
}
|
||||
/*d_printf(">>>close: resolved path as %s\n", targetpath);*/
|
||||
|
||||
|
||||
if (!cli_close(targetcli, file->cli_fd)) {
|
||||
|
||||
|
||||
DEBUG(3, ("cli_close failed on %s. purging server.\n",
|
||||
file->fname));
|
||||
/* Deallocate slot and remove the server
|
||||
@ -476,14 +481,14 @@ SMBC_close_ctx(SMBCCTX *context,
|
||||
(context->server.remove_unused_server_fn)(context, srv);
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
DLIST_REMOVE(context->internal->files, file);
|
||||
SAFE_FREE(file->fname);
|
||||
SAFE_FREE(file);
|
||||
TALLOC_FREE(frame);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -508,14 +513,14 @@ SMBC_getatr(SMBCCTX * context,
|
||||
struct cli_state *targetcli = NULL;
|
||||
time_t write_time;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* path fixup for . and .. */
|
||||
if (strequal(path, ".") || strequal(path, "..")) {
|
||||
fixedpath = talloc_strdup(frame, "\\");
|
||||
@ -535,14 +540,14 @@ SMBC_getatr(SMBCCTX * context,
|
||||
trim_string(fixedpath, NULL, "\\.");
|
||||
}
|
||||
DEBUG(4,("SMBC_getatr: sending qpathinfo\n"));
|
||||
|
||||
|
||||
if (!cli_resolve_path(frame, "", srv->cli, fixedpath,
|
||||
&targetcli, &targetpath)) {
|
||||
&targetcli, &targetpath)) {
|
||||
d_printf("Couldn't resolve %s\n", path);
|
||||
TALLOC_FREE(frame);
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
if (!srv->no_pathinfo2 &&
|
||||
cli_qpathinfo2(targetcli, targetpath,
|
||||
create_time_ts,
|
||||
@ -553,45 +558,45 @@ SMBC_getatr(SMBCCTX * context,
|
||||
TALLOC_FREE(frame);
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/* if this is NT then don't bother with the getatr */
|
||||
if (targetcli->capabilities & CAP_NT_SMBS) {
|
||||
errno = EPERM;
|
||||
TALLOC_FREE(frame);
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
if (cli_getatr(targetcli, targetpath, mode, size, &write_time)) {
|
||||
|
||||
|
||||
struct timespec w_time_ts;
|
||||
|
||||
|
||||
w_time_ts = convert_time_t_to_timespec(write_time);
|
||||
|
||||
|
||||
if (write_time_ts != NULL) {
|
||||
*write_time_ts = w_time_ts;
|
||||
}
|
||||
|
||||
|
||||
if (create_time_ts != NULL) {
|
||||
*create_time_ts = w_time_ts;
|
||||
}
|
||||
|
||||
|
||||
if (access_time_ts != NULL) {
|
||||
*access_time_ts = w_time_ts;
|
||||
}
|
||||
|
||||
|
||||
if (change_time_ts != NULL) {
|
||||
*change_time_ts = w_time_ts;
|
||||
}
|
||||
|
||||
|
||||
srv->no_pathinfo2 = True;
|
||||
TALLOC_FREE(frame);
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
errno = EPERM;
|
||||
TALLOC_FREE(frame);
|
||||
return False;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -615,7 +620,7 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
|
||||
int fd;
|
||||
int ret;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
/*
|
||||
* First, try setpathinfo (if qpathinfo succeeded), for it is the
|
||||
* modern function for "new code" to be using, and it works given a
|
||||
@ -629,7 +634,7 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
|
||||
write_time,
|
||||
change_time,
|
||||
mode)) {
|
||||
|
||||
|
||||
/*
|
||||
* setpathinfo is not supported; go to plan B.
|
||||
*
|
||||
@ -639,27 +644,27 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
|
||||
* cli_setattrE() which should work on all OS versions, and
|
||||
* supports both times.
|
||||
*/
|
||||
|
||||
|
||||
/* Don't try {q,set}pathinfo() again, with this server */
|
||||
srv->no_pathinfo = True;
|
||||
|
||||
|
||||
/* Open the file */
|
||||
if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) {
|
||||
|
||||
|
||||
errno = SMBC_errno(context, srv->cli);
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Set the new attributes */
|
||||
ret = cli_setattrE(srv->cli, fd,
|
||||
change_time,
|
||||
access_time,
|
||||
write_time);
|
||||
|
||||
|
||||
/* Close the file */
|
||||
cli_close(srv->cli, fd);
|
||||
|
||||
|
||||
/*
|
||||
* Unfortunately, setattrE() doesn't have a provision for
|
||||
* setting the access mode (attributes). We'll have to try
|
||||
@ -669,14 +674,14 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
|
||||
if (ret && mode != (uint16) -1) {
|
||||
ret = cli_setatr(srv->cli, path, mode, 0);
|
||||
}
|
||||
|
||||
|
||||
if (! ret) {
|
||||
errno = SMBC_errno(context, srv->cli);
|
||||
TALLOC_FREE(frame);
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return True;
|
||||
}
|
||||
@ -697,56 +702,56 @@ SMBC_lseek_ctx(SMBCCTX *context,
|
||||
char *targetpath = NULL;
|
||||
struct cli_state *targetcli = NULL;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!file || !SMBC_dlist_contains(context->internal->files, file)) {
|
||||
|
||||
|
||||
errno = EBADF;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!file->file) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1; /* Can't lseek a dir ... */
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
file->offset = offset;
|
||||
break;
|
||||
|
||||
|
||||
case SEEK_CUR:
|
||||
file->offset += offset;
|
||||
break;
|
||||
|
||||
|
||||
case SEEK_END:
|
||||
/*d_printf(">>>lseek: parsing %s\n", file->fname);*/
|
||||
if (SMBC_parse_path(frame,
|
||||
context,
|
||||
file->fname,
|
||||
NULL,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
context,
|
||||
file->fname,
|
||||
NULL,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*d_printf(">>>lseek: resolving %s\n", path);*/
|
||||
if (!cli_resolve_path(frame, "", file->srv->cli, path,
|
||||
&targetcli, &targetpath)) {
|
||||
@ -755,32 +760,32 @@ SMBC_lseek_ctx(SMBCCTX *context,
|
||||
return -1;
|
||||
}
|
||||
/*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/
|
||||
|
||||
|
||||
if (!cli_qfileinfo(targetcli, file->cli_fd, NULL,
|
||||
&size, NULL, NULL, NULL, NULL, NULL))
|
||||
{
|
||||
SMB_OFF_T b_size = size;
|
||||
SMB_OFF_T b_size = size;
|
||||
if (!cli_getattrE(targetcli, file->cli_fd,
|
||||
NULL, &b_size, NULL, NULL, NULL))
|
||||
{
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
} else
|
||||
size = b_size;
|
||||
{
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
} else
|
||||
size = b_size;
|
||||
}
|
||||
file->offset = size + offset;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return file->offset;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -802,26 +807,26 @@ SMBC_ftruncate_ctx(SMBCCTX *context,
|
||||
char *targetpath = NULL;
|
||||
struct cli_state *targetcli = NULL;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!file || !SMBC_dlist_contains(context->internal->files, file)) {
|
||||
errno = EBADF;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!file->file) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*d_printf(">>>fstat: parsing %s\n", file->fname);*/
|
||||
if (SMBC_parse_path(frame,
|
||||
context,
|
||||
@ -837,7 +842,7 @@ SMBC_ftruncate_ctx(SMBCCTX *context,
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*d_printf(">>>fstat: resolving %s\n", path);*/
|
||||
if (!cli_resolve_path(frame, "", file->srv->cli, path,
|
||||
&targetcli, &targetpath)) {
|
||||
@ -846,14 +851,14 @@ SMBC_ftruncate_ctx(SMBCCTX *context,
|
||||
return -1;
|
||||
}
|
||||
/*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/
|
||||
|
||||
|
||||
if (!cli_ftruncate(targetcli, file->cli_fd, size)) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
@ -50,24 +50,24 @@ SMBC_errno(SMBCCTX *context,
|
||||
struct cli_state *c)
|
||||
{
|
||||
int ret = cli_errno(c);
|
||||
|
||||
|
||||
if (cli_is_dos_error(c)) {
|
||||
uint8 eclass;
|
||||
uint32 ecode;
|
||||
|
||||
|
||||
cli_dos_error(c, &eclass, &ecode);
|
||||
|
||||
DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n",
|
||||
(int)eclass, (int)ecode, (int)ecode, ret));
|
||||
} else {
|
||||
NTSTATUS status;
|
||||
|
||||
|
||||
status = cli_nt_error(c);
|
||||
|
||||
|
||||
DEBUG(3,("smbc errno %s -> %d\n",
|
||||
nt_errstr(status), ret));
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -31,13 +31,13 @@
|
||||
static int
|
||||
hex2int( unsigned int _char )
|
||||
{
|
||||
if ( _char >= 'A' && _char <='F')
|
||||
return _char - 'A' + 10;
|
||||
if ( _char >= 'a' && _char <='f')
|
||||
return _char - 'a' + 10;
|
||||
if ( _char >= '0' && _char <='9')
|
||||
return _char - '0';
|
||||
return -1;
|
||||
if ( _char >= 'A' && _char <='F')
|
||||
return _char - 'A' + 10;
|
||||
if ( _char >= 'a' && _char <='f')
|
||||
return _char - 'a' + 10;
|
||||
if ( _char >= '0' && _char <='9')
|
||||
return _char - '0';
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -60,19 +60,19 @@ urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src)
|
||||
int err_count = 0;
|
||||
size_t newlen = 1;
|
||||
char *p, *dest;
|
||||
|
||||
|
||||
if (old_length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
*pp_dest = NULL;
|
||||
for (i = 0; i < old_length; ) {
|
||||
unsigned char character = src[i++];
|
||||
|
||||
|
||||
if (character == '%') {
|
||||
int a = i+1 < old_length ? hex2int(src[i]) : -1;
|
||||
int b = i+1 < old_length ? hex2int(src[i+1]) : -1;
|
||||
|
||||
|
||||
/* Replace valid sequence */
|
||||
if (a != -1 && b != -1) {
|
||||
/* Replace valid %xx sequence with %dd */
|
||||
@ -87,20 +87,20 @@ urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src)
|
||||
}
|
||||
newlen++;
|
||||
}
|
||||
|
||||
|
||||
dest = TALLOC_ARRAY(ctx, char, newlen);
|
||||
if (!dest) {
|
||||
return err_count;
|
||||
}
|
||||
|
||||
|
||||
err_count = 0;
|
||||
for (p = dest, i = 0; i < old_length; ) {
|
||||
unsigned char character = src[i++];
|
||||
|
||||
|
||||
if (character == '%') {
|
||||
int a = i+1 < old_length ? hex2int(src[i]) : -1;
|
||||
int b = i+1 < old_length ? hex2int(src[i+1]) : -1;
|
||||
|
||||
|
||||
/* Replace valid sequence */
|
||||
if (a != -1 && b != -1) {
|
||||
/* Replace valid %xx sequence with %dd */
|
||||
@ -115,7 +115,7 @@ urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src)
|
||||
}
|
||||
*p++ = character;
|
||||
}
|
||||
|
||||
|
||||
*p = '\0';
|
||||
*pp_dest = dest;
|
||||
return err_count;
|
||||
@ -129,7 +129,7 @@ SMBC_urldecode(char *dest,
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
char *pdest;
|
||||
int ret = urldecode_talloc(frame, &pdest, src);
|
||||
|
||||
|
||||
if (pdest) {
|
||||
strlcpy(dest, pdest, max_dest_len);
|
||||
}
|
||||
@ -151,9 +151,9 @@ SMBC_urlencode(char *dest,
|
||||
int max_dest_len)
|
||||
{
|
||||
char hex[] = "0123456789ABCDEF";
|
||||
|
||||
|
||||
for (; *src != '\0' && max_dest_len >= 3; src++) {
|
||||
|
||||
|
||||
if ((*src < '0' &&
|
||||
*src != '-' &&
|
||||
*src != '.') ||
|
||||
@ -172,10 +172,10 @@ SMBC_urlencode(char *dest,
|
||||
max_dest_len--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*dest++ = '\0';
|
||||
max_dest_len--;
|
||||
|
||||
|
||||
return max_dest_len;
|
||||
}
|
||||
|
||||
@ -196,9 +196,9 @@ SMBC_urlencode(char *dest,
|
||||
*
|
||||
* The method of locating the list of workgroups varies
|
||||
* depending upon the setting of the context variable
|
||||
* context->browse_max_lmb_count. This value determines
|
||||
* the maximum number of local master browsers to query
|
||||
* for the list of workgroups. In order to ensure that
|
||||
* context->options.browse_max_lmb_count. This value
|
||||
* determines the maximum number of local master browsers to
|
||||
* query for the list of workgroups. In order to ensure that
|
||||
* a complete list of workgroups is obtained, all master
|
||||
* browsers must be queried, but if there are many
|
||||
* workgroups, the time spent querying can begin to add up.
|
||||
@ -234,75 +234,75 @@ SMBC_parse_path(TALLOC_CTX *ctx,
|
||||
const char *p;
|
||||
char *q, *r;
|
||||
int len;
|
||||
|
||||
|
||||
/* Ensure these returns are at least valid pointers. */
|
||||
*pp_server = talloc_strdup(ctx, "");
|
||||
*pp_share = talloc_strdup(ctx, "");
|
||||
*pp_path = talloc_strdup(ctx, "");
|
||||
*pp_user = talloc_strdup(ctx, "");
|
||||
*pp_password = talloc_strdup(ctx, "");
|
||||
|
||||
|
||||
if (!*pp_server || !*pp_share || !*pp_path ||
|
||||
!*pp_user || !*pp_password) {
|
||||
!*pp_user || !*pp_password) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Assume we wont find an authentication domain to parse, so default
|
||||
* to the workgroup in the provided context.
|
||||
*/
|
||||
if (pp_workgroup != NULL) {
|
||||
*pp_workgroup =
|
||||
talloc_strdup(ctx, context->config.workgroup);
|
||||
talloc_strdup(ctx, context->config.workgroup);
|
||||
}
|
||||
|
||||
|
||||
if (pp_options) {
|
||||
*pp_options = talloc_strdup(ctx, "");
|
||||
}
|
||||
s = talloc_strdup(ctx, fname);
|
||||
|
||||
|
||||
/* see if it has the right prefix */
|
||||
len = strlen(smbc_prefix);
|
||||
if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) {
|
||||
return -1; /* What about no smb: ? */
|
||||
}
|
||||
|
||||
|
||||
p = s + len;
|
||||
|
||||
|
||||
/* Watch the test below, we are testing to see if we should exit */
|
||||
|
||||
|
||||
if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) {
|
||||
DEBUG(1, ("Invalid path (does not begin with smb://"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
p += 2; /* Skip the double slash */
|
||||
|
||||
|
||||
/* See if any options were specified */
|
||||
if ((q = strrchr(p, '?')) != NULL ) {
|
||||
/* There are options. Null terminate here and point to them */
|
||||
*q++ = '\0';
|
||||
|
||||
|
||||
DEBUG(4, ("Found options '%s'", q));
|
||||
|
||||
|
||||
/* Copy the options */
|
||||
if (*pp_options != NULL) {
|
||||
TALLOC_FREE(*pp_options);
|
||||
*pp_options = talloc_strdup(ctx, q);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (*p == '\0') {
|
||||
goto decoding;
|
||||
}
|
||||
|
||||
|
||||
if (*p == '/') {
|
||||
int wl = strlen(context->config.workgroup);
|
||||
|
||||
|
||||
if (wl > 16) {
|
||||
wl = 16;
|
||||
}
|
||||
|
||||
|
||||
*pp_server = talloc_strdup(ctx, context->config.workgroup);
|
||||
if (!*pp_server) {
|
||||
return -1;
|
||||
@ -310,27 +310,27 @@ SMBC_parse_path(TALLOC_CTX *ctx,
|
||||
*pp_server[wl] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ok, its for us. Now parse out the server, share etc.
|
||||
*
|
||||
* However, we want to parse out [[domain;]user[:password]@] if it
|
||||
* exists ...
|
||||
*/
|
||||
|
||||
|
||||
/* check that '@' occurs before '/', if '/' exists at all */
|
||||
q = strchr_m(p, '@');
|
||||
r = strchr_m(p, '/');
|
||||
if (q && (!r || q < r)) {
|
||||
char *userinfo = NULL;
|
||||
const char *u;
|
||||
|
||||
|
||||
next_token_no_ltrim_talloc(ctx, &p, &userinfo, "@");
|
||||
if (!userinfo) {
|
||||
return -1;
|
||||
}
|
||||
u = userinfo;
|
||||
|
||||
|
||||
if (strchr_m(u, ';')) {
|
||||
char *workgroup;
|
||||
next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";");
|
||||
@ -341,7 +341,7 @@ SMBC_parse_path(TALLOC_CTX *ctx,
|
||||
*pp_workgroup = workgroup;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (strchr_m(u, ':')) {
|
||||
next_token_no_ltrim_talloc(ctx, &u, pp_user, ":");
|
||||
if (!*pp_user) {
|
||||
@ -358,27 +358,27 @@ SMBC_parse_path(TALLOC_CTX *ctx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!next_token_talloc(ctx, &p, pp_server, "/")) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (*p == (char)0) {
|
||||
goto decoding; /* That's it ... */
|
||||
}
|
||||
|
||||
|
||||
if (!next_token_talloc(ctx, &p, pp_share, "/")) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prepend a leading slash if there's a file path, as required by
|
||||
* NetApp filers.
|
||||
*/
|
||||
if (*p != '\0') {
|
||||
*pp_path = talloc_asprintf(ctx,
|
||||
"\\%s",
|
||||
p);
|
||||
"\\%s",
|
||||
p);
|
||||
} else {
|
||||
*pp_path = talloc_strdup(ctx, "");
|
||||
}
|
||||
@ -386,15 +386,15 @@ SMBC_parse_path(TALLOC_CTX *ctx,
|
||||
return -1;
|
||||
}
|
||||
string_replace(*pp_path, '/', '\\');
|
||||
|
||||
decoding:
|
||||
|
||||
|
||||
decoding:
|
||||
|
||||
(void) urldecode_talloc(ctx, pp_path, *pp_path);
|
||||
(void) urldecode_talloc(ctx, pp_server, *pp_server);
|
||||
(void) urldecode_talloc(ctx, pp_share, *pp_share);
|
||||
(void) urldecode_talloc(ctx, pp_user, *pp_user);
|
||||
(void) urldecode_talloc(ctx, pp_password, *pp_password);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -41,39 +41,39 @@ SMBC_open_print_job_ctx(SMBCCTX *context,
|
||||
char *password = NULL;
|
||||
char *path = NULL;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (!fname) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
DEBUG(4, ("SMBC_open_print_job_ctx(%s)\n", fname));
|
||||
|
||||
|
||||
if (SMBC_parse_path(frame,
|
||||
context,
|
||||
fname,
|
||||
NULL,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
context,
|
||||
fname,
|
||||
NULL,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* What if the path is empty, or the file exists? */
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return (context->posix_emu.open_fn)(context, fname, O_WRONLY, 666);
|
||||
}
|
||||
@ -98,77 +98,79 @@ SMBC_print_file_ctx(SMBCCTX *c_file,
|
||||
int tot_bytes = 0;
|
||||
char buf[4096];
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
if (!c_file || !c_file->internal->initialized ||
|
||||
!c_print || !c_print->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!fname && !printq) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Try to open the file for reading ... */
|
||||
|
||||
if ((long)(fid1 = smbc_getFunctionOpen(c_file)(c_file, fname, O_RDONLY, 0666)) < 0) {
|
||||
|
||||
if ((long)(fid1 = smbc_getFunctionOpen(c_file)(c_file, fname,
|
||||
O_RDONLY, 0666)) < 0) {
|
||||
DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno));
|
||||
TALLOC_FREE(frame);
|
||||
return -1; /* smbc_open sets errno */
|
||||
}
|
||||
|
||||
|
||||
/* Now, try to open the printer file for writing */
|
||||
|
||||
if ((long)(fid2 = smbc_getFunctionOpenPrintJob(c_print)(c_print, printq)) < 0) {
|
||||
|
||||
|
||||
if ((long)(fid2 = smbc_getFunctionOpenPrintJob(c_print)(c_print,
|
||||
printq)) < 0) {
|
||||
|
||||
saverr = errno; /* Save errno */
|
||||
smbc_getFunctionClose(c_file)(c_file, fid1);
|
||||
errno = saverr;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
while ((bytes = smbc_getFunctionRead(c_file)(c_file, fid1,
|
||||
buf, sizeof(buf))) > 0) {
|
||||
|
||||
|
||||
tot_bytes += bytes;
|
||||
|
||||
|
||||
if ((smbc_getFunctionWrite(c_print)(c_print, fid2,
|
||||
buf, bytes)) < 0) {
|
||||
|
||||
|
||||
saverr = errno;
|
||||
smbc_getFunctionClose(c_file)(c_file, fid1);
|
||||
smbc_getFunctionClose(c_print)(c_print, fid2);
|
||||
errno = saverr;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
saverr = errno;
|
||||
|
||||
smbc_getFunctionClose(c_file)(c_file, fid1); /* We have to close these anyway */
|
||||
|
||||
smbc_getFunctionClose(c_file)(c_file, fid1);
|
||||
smbc_getFunctionClose(c_print)(c_print, fid2);
|
||||
|
||||
|
||||
if (bytes < 0) {
|
||||
|
||||
|
||||
errno = saverr;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return tot_bytes;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -188,37 +190,37 @@ SMBC_list_print_jobs_ctx(SMBCCTX *context,
|
||||
char *workgroup = NULL;
|
||||
char *path = NULL;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!fname) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname));
|
||||
|
||||
|
||||
if (SMBC_parse_path(frame,
|
||||
context,
|
||||
fname,
|
||||
&workgroup,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
context,
|
||||
fname,
|
||||
&workgroup,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!user || user[0] == (char)0) {
|
||||
user = talloc_strdup(frame, context->config.user);
|
||||
if (!user) {
|
||||
@ -227,25 +229,25 @@ SMBC_list_print_jobs_ctx(SMBCCTX *context,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
srv = SMBC_server(frame, context, True,
|
||||
server, share, &workgroup, &user, &password);
|
||||
|
||||
|
||||
if (!srv) {
|
||||
TALLOC_FREE(frame);
|
||||
return -1; /* errno set by SMBC_server */
|
||||
}
|
||||
|
||||
|
||||
if (cli_print_queue(srv->cli,
|
||||
(void (*)(struct print_job_info *))fn) < 0) {
|
||||
errno = SMBC_errno(context, srv->cli);
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -266,37 +268,37 @@ SMBC_unlink_print_job_ctx(SMBCCTX *context,
|
||||
char *path = NULL;
|
||||
int err;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!fname) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname));
|
||||
|
||||
|
||||
if (SMBC_parse_path(frame,
|
||||
context,
|
||||
fname,
|
||||
&workgroup,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
context,
|
||||
fname,
|
||||
&workgroup,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!user || user[0] == (char)0) {
|
||||
user = talloc_strdup(frame, context->config.user);
|
||||
if (!user) {
|
||||
@ -305,30 +307,30 @@ SMBC_unlink_print_job_ctx(SMBCCTX *context,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
srv = SMBC_server(frame, context, True,
|
||||
server, share, &workgroup, &user, &password);
|
||||
|
||||
|
||||
if (!srv) {
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return -1; /* errno set by SMBC_server */
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ((err = cli_printjob_del(srv->cli, id)) != 0) {
|
||||
|
||||
|
||||
if (err < 0)
|
||||
errno = SMBC_errno(context, srv->cli);
|
||||
else if (err == ERRnosuchprintjob)
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ SMBC_check_server(SMBCCTX * context,
|
||||
{
|
||||
socklen_t size;
|
||||
struct sockaddr addr;
|
||||
|
||||
|
||||
size = sizeof(addr);
|
||||
return (getpeername(server->cli->fd, &addr, &size) == -1);
|
||||
}
|
||||
@ -56,12 +56,12 @@ SMBC_remove_unused_server(SMBCCTX * context,
|
||||
SMBCSRV * srv)
|
||||
{
|
||||
SMBCFILE * file;
|
||||
|
||||
|
||||
/* are we being fooled ? */
|
||||
if (!context || !context->internal->initialized || !srv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Check all open files/directories for a relation with this server */
|
||||
for (file = context->internal->files; file; file = file->next) {
|
||||
if (file->srv == srv) {
|
||||
@ -72,16 +72,16 @@ SMBC_remove_unused_server(SMBCCTX * context,
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DLIST_REMOVE(context->internal->servers, srv);
|
||||
|
||||
|
||||
cli_shutdown(srv->cli);
|
||||
srv->cli = NULL;
|
||||
|
||||
|
||||
DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv));
|
||||
|
||||
|
||||
(context->cache.remove_cached_server_fn)(context, srv);
|
||||
|
||||
|
||||
SAFE_FREE(srv);
|
||||
return 0;
|
||||
}
|
||||
@ -101,21 +101,21 @@ SMBC_call_auth_fn(TALLOC_CTX *ctx,
|
||||
fstring workgroup;
|
||||
fstring username;
|
||||
fstring password;
|
||||
|
||||
|
||||
strlcpy(workgroup, *pp_workgroup, sizeof(workgroup));
|
||||
strlcpy(username, *pp_username, sizeof(username));
|
||||
strlcpy(password, *pp_password, sizeof(password));
|
||||
|
||||
|
||||
(context->server.get_auth_data_fn)(
|
||||
server, share,
|
||||
workgroup, sizeof(workgroup),
|
||||
username, sizeof(username),
|
||||
password, sizeof(password));
|
||||
|
||||
|
||||
TALLOC_FREE(*pp_workgroup);
|
||||
TALLOC_FREE(*pp_username);
|
||||
TALLOC_FREE(*pp_password);
|
||||
|
||||
|
||||
*pp_workgroup = talloc_strdup(ctx, workgroup);
|
||||
*pp_username = talloc_strdup(ctx, username);
|
||||
*pp_password = talloc_strdup(ctx, password);
|
||||
@ -144,23 +144,23 @@ SMBC_find_server(TALLOC_CTX *ctx,
|
||||
{
|
||||
SMBCSRV *srv;
|
||||
int auth_called = 0;
|
||||
|
||||
check_server_cache:
|
||||
|
||||
|
||||
check_server_cache:
|
||||
|
||||
srv = (context->cache.get_cached_server_fn)(context,
|
||||
server, share,
|
||||
*pp_workgroup,
|
||||
*pp_username);
|
||||
|
||||
|
||||
if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] ||
|
||||
!*pp_password || !(*pp_password)[0])) {
|
||||
!*pp_password || !(*pp_password)[0])) {
|
||||
SMBC_call_auth_fn(ctx, context, server, share,
|
||||
pp_workgroup, pp_username, pp_password);
|
||||
|
||||
pp_workgroup, pp_username, pp_password);
|
||||
|
||||
if (!pp_workgroup || !pp_username || !pp_password) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* However, smbc_auth_fn may have picked up info relating to
|
||||
* an existing connection, so try for an existing connection
|
||||
@ -168,9 +168,9 @@ SMBC_find_server(TALLOC_CTX *ctx,
|
||||
*/
|
||||
auth_called = 1;
|
||||
goto check_server_cache;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (srv) {
|
||||
if ((context->server.check_server_fn)(context, srv)) {
|
||||
/*
|
||||
@ -189,17 +189,17 @@ SMBC_find_server(TALLOC_CTX *ctx,
|
||||
(context->cache.remove_cached_server_fn)(context,
|
||||
srv);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Maybe there are more cached connections to this
|
||||
* server
|
||||
*/
|
||||
goto check_server_cache;
|
||||
}
|
||||
|
||||
|
||||
return srv;
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -234,25 +234,25 @@ SMBC_server(TALLOC_CTX *ctx,
|
||||
int port_try_next;
|
||||
const char *username_used;
|
||||
NTSTATUS status;
|
||||
|
||||
|
||||
zero_addr(&ss);
|
||||
ZERO_STRUCT(c);
|
||||
|
||||
|
||||
if (server[0] == 0) {
|
||||
errno = EPERM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Look for a cached connection */
|
||||
srv = SMBC_find_server(ctx, context, server, share,
|
||||
pp_workgroup, pp_username, pp_password);
|
||||
|
||||
pp_workgroup, pp_username, pp_password);
|
||||
|
||||
/*
|
||||
* If we found a connection and we're only allowed one share per
|
||||
* server...
|
||||
*/
|
||||
if (srv && *share != '\0' && context->internal->one_share_per_server) {
|
||||
|
||||
if (srv && *share != '\0' && context->options.one_share_per_server) {
|
||||
|
||||
/*
|
||||
* ... then if there's no current connection to the share,
|
||||
* connect to it. SMBC_find_server(), or rather the function
|
||||
@ -264,8 +264,10 @@ SMBC_server(TALLOC_CTX *ctx,
|
||||
if (srv->cli->cnum == (uint16) -1) {
|
||||
/* Ensure we have accurate auth info */
|
||||
SMBC_call_auth_fn(ctx, context, server, share,
|
||||
pp_workgroup, pp_username, pp_password);
|
||||
|
||||
pp_workgroup,
|
||||
pp_username,
|
||||
pp_password);
|
||||
|
||||
if (!*pp_workgroup || !*pp_username || !*pp_password) {
|
||||
errno = ENOMEM;
|
||||
cli_shutdown(srv->cli);
|
||||
@ -274,17 +276,17 @@ SMBC_server(TALLOC_CTX *ctx,
|
||||
srv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We don't need to renegotiate encryption
|
||||
* here as the encryption context is not per
|
||||
* tid.
|
||||
*/
|
||||
|
||||
|
||||
if (!cli_send_tconX(srv->cli, share, "?????",
|
||||
*pp_password,
|
||||
strlen(*pp_password)+1)) {
|
||||
|
||||
*pp_password,
|
||||
strlen(*pp_password)+1)) {
|
||||
|
||||
errno = SMBC_errno(context, srv->cli);
|
||||
cli_shutdown(srv->cli);
|
||||
srv->cli = NULL;
|
||||
@ -292,7 +294,7 @@ SMBC_server(TALLOC_CTX *ctx,
|
||||
srv);
|
||||
srv = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Regenerate the dev value since it's based on both
|
||||
* server and share
|
||||
@ -303,51 +305,51 @@ SMBC_server(TALLOC_CTX *ctx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If we have a connection... */
|
||||
if (srv) {
|
||||
|
||||
|
||||
/* ... then we're done here. Give 'em what they came for. */
|
||||
return srv;
|
||||
}
|
||||
|
||||
|
||||
/* If we're not asked to connect when a connection doesn't exist... */
|
||||
if (! connect_if_not_found) {
|
||||
/* ... then we're done here. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (!*pp_workgroup || !*pp_username || !*pp_password) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
make_nmb_name(&calling, context->config.netbios_name, 0x0);
|
||||
make_nmb_name(&called , server, 0x20);
|
||||
|
||||
|
||||
DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server));
|
||||
|
||||
|
||||
DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
|
||||
|
||||
again:
|
||||
|
||||
|
||||
again:
|
||||
|
||||
zero_addr(&ss);
|
||||
|
||||
|
||||
/* have to open a new connection */
|
||||
if ((c = cli_initialise()) == NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS) {
|
||||
c->use_kerberos = True;
|
||||
}
|
||||
if (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) {
|
||||
c->fallback_after_kerberos = True;
|
||||
}
|
||||
|
||||
|
||||
c->timeout = context->config.timeout;
|
||||
|
||||
|
||||
/*
|
||||
* Force use of port 139 for first try if share is $IPC, empty, or
|
||||
* null, so browse lists can work
|
||||
@ -359,15 +361,15 @@ SMBC_server(TALLOC_CTX *ctx,
|
||||
port_try_first = 445;
|
||||
port_try_next = 139;
|
||||
}
|
||||
|
||||
|
||||
c->port = port_try_first;
|
||||
|
||||
|
||||
status = cli_connect(c, server_n, &ss);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
|
||||
|
||||
/* First connection attempt failed. Try alternate port. */
|
||||
c->port = port_try_next;
|
||||
|
||||
|
||||
status = cli_connect(c, server_n, &ss);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
cli_shutdown(c);
|
||||
@ -375,33 +377,36 @@ SMBC_server(TALLOC_CTX *ctx,
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!cli_session_request(c, &calling, &called)) {
|
||||
cli_shutdown(c);
|
||||
if (strcmp(called.name, "*SMBSERVER")) {
|
||||
make_nmb_name(&called , "*SMBSERVER", 0x20);
|
||||
goto again;
|
||||
} else { /* Try one more time, but ensure we don't loop */
|
||||
|
||||
|
||||
/* Only try this if server is an IP address ... */
|
||||
|
||||
|
||||
if (is_ipaddress(server) && !tried_reverse) {
|
||||
fstring remote_name;
|
||||
struct sockaddr_storage rem_ss;
|
||||
|
||||
|
||||
if (!interpret_string_addr(&rem_ss, server,
|
||||
NI_NUMERICHOST)) {
|
||||
NI_NUMERICHOST)) {
|
||||
DEBUG(4, ("Could not convert IP address "
|
||||
"%s to struct sockaddr_storage\n",
|
||||
server));
|
||||
"%s to struct sockaddr_storage\n",
|
||||
server));
|
||||
errno = ETIMEDOUT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
tried_reverse++; /* Yuck */
|
||||
|
||||
if (name_status_find("*", 0, 0, &rem_ss, remote_name)) {
|
||||
make_nmb_name(&called, remote_name, 0x20);
|
||||
|
||||
if (name_status_find("*", 0, 0,
|
||||
&rem_ss, remote_name)) {
|
||||
make_nmb_name(&called,
|
||||
remote_name,
|
||||
0x20);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
@ -409,64 +414,66 @@ SMBC_server(TALLOC_CTX *ctx,
|
||||
errno = ETIMEDOUT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
DEBUG(4,(" session request ok\n"));
|
||||
|
||||
|
||||
if (!cli_negprot(c)) {
|
||||
cli_shutdown(c);
|
||||
errno = ETIMEDOUT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
username_used = *pp_username;
|
||||
|
||||
|
||||
if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
|
||||
*pp_password, strlen(*pp_password),
|
||||
*pp_password, strlen(*pp_password),
|
||||
*pp_password,
|
||||
strlen(*pp_password),
|
||||
*pp_password,
|
||||
strlen(*pp_password),
|
||||
*pp_workgroup))) {
|
||||
|
||||
|
||||
/* Failed. Try an anonymous login, if allowed by flags. */
|
||||
username_used = "";
|
||||
|
||||
|
||||
if ((context->flags.bits &
|
||||
SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) ||
|
||||
!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
|
||||
*pp_password, 1,
|
||||
*pp_password, 0,
|
||||
*pp_workgroup))) {
|
||||
|
||||
|
||||
cli_shutdown(c);
|
||||
errno = EPERM;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DEBUG(4,(" session setup ok\n"));
|
||||
|
||||
|
||||
if (!cli_send_tconX(c, share, "?????",
|
||||
*pp_password, strlen(*pp_password)+1)) {
|
||||
errno = SMBC_errno(context, c);
|
||||
cli_shutdown(c);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
DEBUG(4,(" tconx ok\n"));
|
||||
|
||||
|
||||
if (context->internal->smb_encryption_level) {
|
||||
/* Attempt UNIX smb encryption. */
|
||||
if (!NT_STATUS_IS_OK(cli_force_encryption(c,
|
||||
username_used,
|
||||
*pp_password,
|
||||
*pp_workgroup))) {
|
||||
|
||||
username_used,
|
||||
*pp_password,
|
||||
*pp_workgroup))) {
|
||||
|
||||
/*
|
||||
* context->smb_encryption_level == 1
|
||||
* means don't fail if encryption can't be negotiated,
|
||||
* == 2 means fail if encryption can't be negotiated.
|
||||
*/
|
||||
|
||||
|
||||
DEBUG(4,(" SMB encrypt failed\n"));
|
||||
|
||||
|
||||
if (context->internal->smb_encryption_level == 2) {
|
||||
cli_shutdown(c);
|
||||
errno = EPERM;
|
||||
@ -475,25 +482,25 @@ SMBC_server(TALLOC_CTX *ctx,
|
||||
}
|
||||
DEBUG(4,(" SMB encrypt ok\n"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Ok, we have got a nice connection
|
||||
* Let's allocate a server structure.
|
||||
*/
|
||||
|
||||
|
||||
srv = SMB_MALLOC_P(SMBCSRV);
|
||||
if (!srv) {
|
||||
errno = ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
ZERO_STRUCTP(srv);
|
||||
srv->cli = c;
|
||||
srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
|
||||
srv->no_pathinfo = False;
|
||||
srv->no_pathinfo2 = False;
|
||||
srv->no_nt_session = False;
|
||||
|
||||
|
||||
/* now add it to the cache (internal or external) */
|
||||
/* Let the cache function set errno if it wants to */
|
||||
errno = 0;
|
||||
@ -509,19 +516,19 @@ SMBC_server(TALLOC_CTX *ctx,
|
||||
}
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
DEBUG(2, ("Server connect ok: //%s/%s: %p\n",
|
||||
server, share, srv));
|
||||
|
||||
|
||||
DLIST_ADD(context->internal->servers, srv);
|
||||
return srv;
|
||||
|
||||
failed:
|
||||
|
||||
failed:
|
||||
cli_shutdown(c);
|
||||
if (!srv) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
SAFE_FREE(srv);
|
||||
return NULL;
|
||||
}
|
||||
@ -545,32 +552,34 @@ SMBC_attr_server(TALLOC_CTX *ctx,
|
||||
struct rpc_pipe_client *pipe_hnd;
|
||||
NTSTATUS nt_status;
|
||||
SMBCSRV *ipc_srv=NULL;
|
||||
|
||||
|
||||
/*
|
||||
* See if we've already created this special connection. Reference
|
||||
* our "special" share name '*IPC$', which is an impossible real share
|
||||
* name due to the leading asterisk.
|
||||
*/
|
||||
ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$",
|
||||
pp_workgroup, pp_username, pp_password);
|
||||
pp_workgroup, pp_username, pp_password);
|
||||
if (!ipc_srv) {
|
||||
|
||||
|
||||
/* We didn't find a cached connection. Get the password */
|
||||
if (!*pp_password || (*pp_password)[0] == '\0') {
|
||||
/* ... then retrieve it now. */
|
||||
SMBC_call_auth_fn(ctx, context, server, share,
|
||||
pp_workgroup, pp_username, pp_password);
|
||||
pp_workgroup,
|
||||
pp_username,
|
||||
pp_password);
|
||||
if (!*pp_workgroup || !*pp_username || !*pp_password) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
flags = 0;
|
||||
if (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS) {
|
||||
flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
|
||||
}
|
||||
|
||||
|
||||
zero_addr(&ss);
|
||||
nt_status = cli_full_connection(&ipc_cli,
|
||||
global_myname(), server,
|
||||
@ -586,23 +595,23 @@ SMBC_attr_server(TALLOC_CTX *ctx,
|
||||
errno = ENOTSUP;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (context->internal->smb_encryption_level) {
|
||||
/* Attempt UNIX smb encryption. */
|
||||
if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli,
|
||||
*pp_username,
|
||||
*pp_password,
|
||||
*pp_workgroup))) {
|
||||
|
||||
*pp_username,
|
||||
*pp_password,
|
||||
*pp_workgroup))) {
|
||||
|
||||
/*
|
||||
* context->smb_encryption_level ==
|
||||
* 1 means don't fail if encryption can't be
|
||||
* negotiated, == 2 means fail if encryption
|
||||
* can't be negotiated.
|
||||
*/
|
||||
|
||||
|
||||
DEBUG(4,(" SMB encrypt failed on IPC$\n"));
|
||||
|
||||
|
||||
if (context->internal->smb_encryption_level == 2) {
|
||||
cli_shutdown(ipc_cli);
|
||||
errno = EPERM;
|
||||
@ -611,49 +620,49 @@ SMBC_attr_server(TALLOC_CTX *ctx,
|
||||
}
|
||||
DEBUG(4,(" SMB encrypt ok on IPC$\n"));
|
||||
}
|
||||
|
||||
|
||||
ipc_srv = SMB_MALLOC_P(SMBCSRV);
|
||||
if (!ipc_srv) {
|
||||
errno = ENOMEM;
|
||||
cli_shutdown(ipc_cli);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ZERO_STRUCTP(ipc_srv);
|
||||
ipc_srv->cli = ipc_cli;
|
||||
|
||||
|
||||
pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli,
|
||||
PI_LSARPC,
|
||||
&nt_status);
|
||||
if (!pipe_hnd) {
|
||||
DEBUG(1, ("cli_nt_session_open fail!\n"));
|
||||
errno = ENOTSUP;
|
||||
cli_shutdown(ipc_srv->cli);
|
||||
free(ipc_srv);
|
||||
return NULL;
|
||||
DEBUG(1, ("cli_nt_session_open fail!\n"));
|
||||
errno = ENOTSUP;
|
||||
cli_shutdown(ipc_srv->cli);
|
||||
free(ipc_srv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Some systems don't support
|
||||
* SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000
|
||||
* so we might as well do it too.
|
||||
*/
|
||||
|
||||
|
||||
nt_status = rpccli_lsa_open_policy(
|
||||
pipe_hnd,
|
||||
talloc_tos(),
|
||||
True,
|
||||
GENERIC_EXECUTE_ACCESS,
|
||||
&ipc_srv->pol);
|
||||
|
||||
pipe_hnd,
|
||||
talloc_tos(),
|
||||
True,
|
||||
GENERIC_EXECUTE_ACCESS,
|
||||
&ipc_srv->pol);
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
errno = SMBC_errno(context, ipc_srv->cli);
|
||||
cli_shutdown(ipc_srv->cli);
|
||||
return NULL;
|
||||
errno = SMBC_errno(context, ipc_srv->cli);
|
||||
cli_shutdown(ipc_srv->cli);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* now add it to the cache (internal or external) */
|
||||
|
||||
|
||||
errno = 0; /* let cache function set errno if it likes */
|
||||
if ((context->cache.add_cached_server_fn)(context, ipc_srv,
|
||||
server,
|
||||
@ -668,9 +677,9 @@ SMBC_attr_server(TALLOC_CTX *ctx,
|
||||
free(ipc_srv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
DLIST_ADD(context->internal->servers, ipc_srv);
|
||||
}
|
||||
|
||||
|
||||
return ipc_srv;
|
||||
}
|
||||
|
@ -33,18 +33,18 @@
|
||||
|
||||
static ino_t
|
||||
generate_inode(SMBCCTX *context,
|
||||
const char *name)
|
||||
const char *name)
|
||||
{
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!*name) return 2; /* FIXME, why 2 ??? */
|
||||
return (ino_t)str_checksum(name);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -54,26 +54,26 @@ generate_inode(SMBCCTX *context,
|
||||
|
||||
static int
|
||||
setup_stat(SMBCCTX *context,
|
||||
struct stat *st,
|
||||
char *fname,
|
||||
SMB_OFF_T size,
|
||||
int mode)
|
||||
struct stat *st,
|
||||
char *fname,
|
||||
SMB_OFF_T size,
|
||||
int mode)
|
||||
{
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
st->st_mode = 0;
|
||||
|
||||
|
||||
if (IS_DOS_DIR(mode)) {
|
||||
st->st_mode = SMBC_DIR_MODE;
|
||||
} else {
|
||||
st->st_mode = SMBC_FILE_MODE;
|
||||
}
|
||||
|
||||
|
||||
if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR;
|
||||
if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP;
|
||||
if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH;
|
||||
if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR;
|
||||
|
||||
|
||||
st->st_size = size;
|
||||
#ifdef HAVE_STAT_ST_BLKSIZE
|
||||
st->st_blksize = 512;
|
||||
@ -86,20 +86,20 @@ setup_stat(SMBCCTX *context,
|
||||
#endif
|
||||
st->st_uid = getuid();
|
||||
st->st_gid = getgid();
|
||||
|
||||
|
||||
if (IS_DOS_DIR(mode)) {
|
||||
st->st_nlink = 2;
|
||||
} else {
|
||||
st->st_nlink = 1;
|
||||
}
|
||||
|
||||
|
||||
if (st->st_ino == 0) {
|
||||
st->st_ino = generate_inode(context, fname);
|
||||
}
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return True; /* FIXME: Is this needed ? */
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -125,37 +125,37 @@ SMBC_stat_ctx(SMBCCTX *context,
|
||||
uint16 mode = 0;
|
||||
SMB_INO_T ino = 0;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL; /* Best I can think of ... */
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!fname) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
DEBUG(4, ("smbc_stat(%s)\n", fname));
|
||||
|
||||
|
||||
if (SMBC_parse_path(frame,
|
||||
context,
|
||||
fname,
|
||||
&workgroup,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
context,
|
||||
fname,
|
||||
&workgroup,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!user || user[0] == (char)0) {
|
||||
user = talloc_strdup(frame,context->config.user);
|
||||
if (!user) {
|
||||
@ -164,15 +164,15 @@ SMBC_stat_ctx(SMBCCTX *context,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
srv = SMBC_server(frame, context, True,
|
||||
server, share, &workgroup, &user, &password);
|
||||
|
||||
|
||||
if (!srv) {
|
||||
TALLOC_FREE(frame);
|
||||
return -1; /* errno set by SMBC_server */
|
||||
}
|
||||
|
||||
|
||||
if (!SMBC_getatr(context, srv, path, &mode, &size,
|
||||
NULL,
|
||||
&access_time_ts,
|
||||
@ -183,19 +183,19 @@ SMBC_stat_ctx(SMBCCTX *context,
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
st->st_ino = ino;
|
||||
|
||||
|
||||
setup_stat(context, st, (char *) fname, size, mode);
|
||||
|
||||
|
||||
set_atimespec(st, access_time_ts);
|
||||
set_ctimespec(st, change_time_ts);
|
||||
set_mtimespec(st, write_time_ts);
|
||||
st->st_dev = srv->dev;
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -221,41 +221,41 @@ SMBC_fstat_ctx(SMBCCTX *context,
|
||||
struct cli_state *targetcli = NULL;
|
||||
SMB_INO_T ino = 0;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
|
||||
if (!context || !context->internal->initialized) {
|
||||
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!file || !SMBC_dlist_contains(context->internal->files, file)) {
|
||||
errno = EBADF;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!file->file) {
|
||||
TALLOC_FREE(frame);
|
||||
return (context->posix_emu.fstatdir_fn)(context, file, st);
|
||||
}
|
||||
|
||||
|
||||
/*d_printf(">>>fstat: parsing %s\n", file->fname);*/
|
||||
if (SMBC_parse_path(frame,
|
||||
context,
|
||||
file->fname,
|
||||
NULL,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
context,
|
||||
file->fname,
|
||||
NULL,
|
||||
&server,
|
||||
&share,
|
||||
&path,
|
||||
&user,
|
||||
&password,
|
||||
NULL)) {
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*d_printf(">>>fstat: resolving %s\n", path);*/
|
||||
if (!cli_resolve_path(frame, "", file->srv->cli, path,
|
||||
&targetcli, &targetpath)) {
|
||||
@ -264,39 +264,39 @@ SMBC_fstat_ctx(SMBCCTX *context,
|
||||
return -1;
|
||||
}
|
||||
/*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/
|
||||
|
||||
|
||||
if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size,
|
||||
NULL,
|
||||
&access_time_ts,
|
||||
&write_time_ts,
|
||||
&change_time_ts,
|
||||
&ino)) {
|
||||
|
||||
|
||||
time_t change_time, access_time, write_time;
|
||||
|
||||
|
||||
if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size,
|
||||
&change_time, &access_time, &write_time)) {
|
||||
|
||||
&change_time, &access_time, &write_time)) {
|
||||
|
||||
errno = EINVAL;
|
||||
TALLOC_FREE(frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
change_time_ts = convert_time_t_to_timespec(change_time);
|
||||
access_time_ts = convert_time_t_to_timespec(access_time);
|
||||
write_time_ts = convert_time_t_to_timespec(write_time);
|
||||
}
|
||||
|
||||
|
||||
st->st_ino = ino;
|
||||
|
||||
|
||||
setup_stat(context, st, file->fname, size, mode);
|
||||
|
||||
|
||||
set_atimespec(st, access_time_ts);
|
||||
set_ctimespec(st, change_time_ts);
|
||||
set_mtimespec(st, write_time_ts);
|
||||
st->st_dev = file->srv->dev;
|
||||
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user