[
  {
    "path": ".gitignore",
    "content": "\n## xcode specific\nbuild/*\n*.pbxuser\n*.mode2v3\n*.mode1v3\n*.perspective\n*.perspectivev3\n*~.nib\n\n## ignore private workspace stuff added by Xcode4\nxcuserdata\nproject.xcworkspace\n*.xcuserdata\n\n## generic files to ignore\n*~\n*.lock\n*.DS_Store\n*.swp\n*.out\n\n## my\ntmp/*\nlibs/*\nsamba/*\nplan\n\n\n"
  },
  {
    "path": "KxSMB/KxSMB-Prefix.pch",
    "content": "//\n// Prefix header for all source files of the 'KxSMB' target in the 'KxSMB' project\n//\n\n#ifdef __OBJC__\n    #import <Foundation/Foundation.h>\n#endif\n"
  },
  {
    "path": "KxSMBProvider.h",
    "content": "//\n//  KxSambaProvider.h\n//  kxsmb project\n//  https://github.com/kolyvan/kxsmb/\n//\n//  Created by Kolyvan on 28.03.13.\n//\n\n/*\n Copyright (c) 2013 Konstantin Bukreev All rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are met:\n \n - Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n \n - Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#import <Foundation/Foundation.h>\n\nextern NSString * const _Nonnull KxSMBErrorDomain;\n\ntypedef enum {\n    \n    KxSMBErrorUnknown,\n    KxSMBErrorInvalidArg,\n    KxSMBErrorInvalidProtocol,\n    KxSMBErrorOutOfMemory,\n    KxSMBErrorAccessDenied,\n    KxSMBErrorInvalidPath,\n    KxSMBErrorPathIsNotDir,\n    KxSMBErrorPathIsDir,\n    KxSMBErrorWorkgroupNotFound,\n    KxSMBErrorShareDoesNotExist,\n    KxSMBErrorItemAlreadyExists,\n    KxSMBErrorDirNotEmpty,\n    KxSMBErrorFileIO,\n    KxSMBErrorConnRefused,\n    KxSMBErrorOpNotPermited,\n\n} KxSMBError;\n\ntypedef enum {\n    \n    KxSMBItemTypeUnknown,\n    KxSMBItemTypeWorkgroup,\n    KxSMBItemTypeServer,\n    KxSMBItemTypeFileShare,\n    KxSMBItemTypePrinter,\n    KxSMBItemTypeComms,\n    KxSMBItemTypeIPC,\n    KxSMBItemTypeDir,\n    KxSMBItemTypeFile,\n    KxSMBItemTypeLink,    \n    \n} KxSMBItemType;\n\n@class KxSMBItem;\n@class KxSMBAuth;\n\ntypedef void (^KxSMBBlock)(id _Nullable result);\ntypedef void (^KxSMBBlockProgress)(KxSMBItem * _Nonnull item, long transferred, BOOL * _Nonnull stop);\n\n@interface KxSMBItemStat : NSObject\n@property(readonly, nonatomic, strong, nonnull) NSDate *lastModified;\n@property(readonly, nonatomic, strong, nonnull) NSDate *lastAccess;\n@property(readonly, nonatomic, strong, nonnull) NSDate *creationTime;\n@property(readonly, nonatomic) SInt64 size;\n@property(readonly, nonatomic) UInt16 mode;\n@end\n\n@interface KxSMBItem : NSObject\n@property(readonly, nonatomic) KxSMBItemType type;\n@property(readonly, nonatomic, strong, nonnull) NSString *path;\n@property(readonly, nonatomic, strong, nonnull) KxSMBItemStat *stat;\n@property(readonly, nonatomic, strong, nullable) KxSMBAuth *auth;\n@end\n\n@class KxSMBItemFile;\n\n@interface KxSMBItemTree : KxSMBItem\n\n- (void) fetchItems:(nullable KxSMBBlock)block;\n\n- (nullable id) fetchItems;\n\n- (void) createFileWithName:(nonnull NSString *)name\n                  overwrite:(BOOL)overwrite\n                      block:(nonnull KxSMBBlock)block;\n\n- (nullable id) createFileWithName:(nonnull NSString *)name\n                         overwrite:(BOOL)overwrite;\n\n- (void) removeWithName:(nonnull NSString *)name\n                  block:(nonnull KxSMBBlock)block;\n\n- (nullable id) removeWithName:(nonnull NSString *)name;\n\n@end\n\n@interface KxSMBItemFile : KxSMBItem\n\n- (void) close;\n\n- (void)readDataOfLength:(NSUInteger)length\n                   block:(nonnull KxSMBBlock)block;\n\n- (nullable id)readDataOfLength:(NSUInteger)length;\n\n- (void)readDataToEndOfFile:(nonnull KxSMBBlock)block;\n\n- (nullable id)readDataToEndOfFile;\n\n- (void)seekToFileOffset:(off_t)offset\n                  whence:(NSInteger)whence\n                   block:(nonnull KxSMBBlock)block;\n\n- (nullable id)seekToFileOffset:(off_t)offset\n                         whence:(NSInteger)whence;\n\n- (void)writeData:(nonnull NSData *)data\n            block:(nonnull KxSMBBlock)block;\n\n- (nullable id)writeData:(nonnull NSData *)data;\n\n@end\n\n@interface KxSMBAuth : NSObject\n@property (readwrite, nonatomic, strong, nullable) NSString *workgroup;\n@property (readwrite, nonatomic, strong, nullable) NSString *username;\n@property (readwrite, nonatomic, strong, nullable) NSString *password;\n\n+ (nullable instancetype) smbAuthWorkgroup:(nullable NSString *)workgroup\n                                  username:(nullable NSString *)username\n                                  password:(nullable NSString *)password;\n\n@end\n\n@protocol KxSMBProviderDelegate <NSObject>\n\n- (nullable KxSMBAuth *) smbRequestAuthServer:(nonnull NSString *)server\n                                        share:(nonnull NSString *)share\n                                    workgroup:(nonnull NSString *)workgroup\n                                     username:(nonnull NSString *)username;\n@end\n\n// smbc_share_mode\ntypedef NS_ENUM(NSUInteger, KxSMBConfigShareMode) {\n    \n    KxSMBConfigShareModeDenyDOS     = 0,\n    KxSMBConfigShareModeDenyAll     = 1,\n    KxSMBConfigShareModeDenyWrite   = 2,\n    KxSMBConfigShareModeDenyRead    = 3,\n    KxSMBConfigShareModeDenyNone    = 4,\n    KxSMBConfigShareModeDenyFCB     = 7,\n};\n\n// smbc_smb_encrypt_level\ntypedef NS_ENUM(NSUInteger, KxSMBConfigEncryptLevel) {\n    \n    KxSMBConfigEncryptLevelNone      = 0,\n    KxSMBConfigEncryptLevelRequest   = 1,\n    KxSMBConfigEncryptLevelRequire   = 2,\n};\n\n@interface KxSMBConfig : NSObject\n@property (readwrite, nonatomic) NSUInteger timeout;\n@property (readwrite, nonatomic) NSUInteger debugLevel;\n@property (readwrite, nonatomic) BOOL debugToStderr;\n@property (readwrite, nonatomic) BOOL fullTimeNames;\n@property (readwrite, nonatomic) KxSMBConfigShareMode shareMode;\n@property (readwrite, nonatomic) KxSMBConfigEncryptLevel encryptionLevel;\n@property (readwrite, nonatomic) BOOL caseSensitive;\n@property (readwrite, nonatomic) NSUInteger browseMaxLmbCount;\n@property (readwrite, nonatomic) BOOL urlEncodeReaddirEntries;\n@property (readwrite, nonatomic) BOOL oneSharePerServer;\n@property (readwrite, nonatomic) BOOL useKerberos;\n@property (readwrite, nonatomic) BOOL fallbackAfterKerberos;\n@property (readwrite, nonatomic) BOOL noAutoAnonymousLogin;\n@property (readwrite, nonatomic) BOOL useCCache;\n@property (readwrite, nonatomic) BOOL useNTHash;\n@property (readwrite, nonatomic, strong, nullable) NSString *netbiosName;\n@property (readwrite, nonatomic, strong, nullable) NSString *workgroup;\n@property (readwrite, nonatomic, strong, nullable) NSString *username;\n@end\n\n@interface KxSMBProvider : NSObject\n\n@property (readwrite, nonatomic, weak) id<KxSMBProviderDelegate> delegate;\n@property (readwrite, nonatomic, strong, nonnull) KxSMBConfig *config;\n@property (readwrite, nonatomic, strong, nullable) dispatch_queue_t completionQueue;\n\n+ (nullable instancetype) sharedSmbProvider;\n\n- (void) fetchAtPath:(nonnull NSString *)path\n                auth:(nullable KxSMBAuth *)auth\n               block:(nonnull KxSMBBlock)block;\n\n- (void) fetchAtPath:(nonnull NSString *)path\n           expandDir:(BOOL)expandDir\n                auth:(nullable KxSMBAuth *)auth\n               block:(nonnull KxSMBBlock)block;\n\n- (nullable id) fetchAtPath:(nonnull NSString *)path\n                       auth:(nullable KxSMBAuth *)auth;\n\n- (nullable id) fetchAtPath:(nonnull NSString *)path\n                  expandDir:(BOOL)expandDir\n                       auth:(nullable KxSMBAuth *)auth;\n\n- (void) createFileAtPath:(nonnull NSString *)path\n                overwrite:(BOOL)overwrite\n                     auth:(nullable KxSMBAuth *)auth\n                    block:(nonnull KxSMBBlock)block;\n\n- (nullable id) createFileAtPath:(nonnull NSString *)path\n                       overwrite:(BOOL)overwrite\n                            auth:(nullable KxSMBAuth *)auth;\n\n- (void) createFolderAtPath:(nonnull NSString *)path\n                       auth:(nullable KxSMBAuth *)auth\n                      block:(nonnull KxSMBBlock)block;\n\n- (nullable id) createFolderAtPath:(nonnull NSString *)path\n                              auth:(nullable KxSMBAuth *)auth;\n\n- (void) removeAtPath:(nonnull NSString *)path\n                 auth:(nullable KxSMBAuth *)auth\n                block:(nonnull KxSMBBlock)block;\n\n- (nullable id) removeAtPath:(nonnull NSString *)path\n                        auth:(nullable KxSMBAuth *)auth;\n\n- (void) copySMBPath:(nonnull NSString *)smbPath\n           localPath:(nonnull NSString *)localPath\n           overwrite:(BOOL)overwrite\n                auth:(nullable KxSMBAuth *)auth\n               block:(nonnull KxSMBBlock)block;\n\n- (void) copyLocalPath:(nonnull NSString *)localPath\n               smbPath:(nonnull NSString *)smbPath\n             overwrite:(BOOL)overwrite\n                  auth:(nullable KxSMBAuth *)auth\n                 block:(nonnull KxSMBBlock)block;\n\n- (void) copySMBPath:(nonnull NSString *)smbPath\n           localPath:(nonnull NSString *)localPath\n           overwrite:(BOOL)overwrite\n                auth:(nullable KxSMBAuth *)auth\n            progress:(nullable KxSMBBlockProgress)progress\n               block:(nonnull KxSMBBlock)block;\n\n- (void) copyLocalPath:(nonnull NSString *)localPath\n               smbPath:(nonnull NSString *)smbPath\n             overwrite:(BOOL)overwrite\n                  auth:(nullable KxSMBAuth *)auth\n              progress:(nullable KxSMBBlockProgress)progress\n                 block:(nonnull KxSMBBlock)block;\n\n- (void) copyFromPath:(nonnull NSString *)oldPath\n               toPath:(nonnull NSString *)newPath\n            overwrite:(BOOL)overwrite\n                 auth:(nullable KxSMBAuth *)auth\n             progress:(nullable KxSMBBlockProgress)progress\n                block:(nonnull KxSMBBlock)block;\n\n- (void) removeFolderAtPath:(nonnull NSString *)path\n                       auth:(nullable KxSMBAuth *)auth\n                      block:(nonnull KxSMBBlock)block;\n\n- (void) renameAtPath:(nonnull NSString *)oldPath\n              newPath:(nonnull NSString *)newPath\n                 auth:(nullable KxSMBAuth *)auth\n                block:(nonnull KxSMBBlock)block;\n\n// without auth (compatible)\n\n- (void) fetchAtPath:(nonnull NSString *)path\n               block:(nullable KxSMBBlock)block;\n\n- (nullable id) fetchAtPath:(nonnull NSString *)path;\n\n- (void) createFileAtPath:(nonnull NSString *)path\n                overwrite:(BOOL)overwrite\n                    block:(nonnull KxSMBBlock)block;\n\n- (nullable id) createFileAtPath:(nonnull NSString *)path\n                       overwrite:(BOOL)overwrite;\n\n- (void) createFolderAtPath:(nonnull NSString *)path\n                      block:(nonnull KxSMBBlock)block;\n\n- (nullable id) createFolderAtPath:(nonnull NSString *)path;\n\n- (void) removeAtPath:(nonnull NSString *)path\n                block:(nonnull KxSMBBlock)block;\n\n- (nullable id) removeAtPath:(nonnull NSString *)path;\n\n- (void) copySMBPath:(nonnull NSString *)smbPath\n           localPath:(nonnull NSString *)localPath\n           overwrite:(BOOL)overwrite\n               block:(nonnull KxSMBBlock)block;\n\n- (void) copyLocalPath:(nonnull NSString *)localPath\n               smbPath:(nonnull NSString *)smbPath\n             overwrite:(BOOL)overwrite\n                 block:(nonnull KxSMBBlock)block;\n\n- (void) copySMBPath:(nonnull NSString *)smbPath\n           localPath:(nonnull NSString *)localPath\n           overwrite:(BOOL)overwrite\n            progress:(nullable KxSMBBlockProgress)progress\n               block:(nonnull KxSMBBlock)block;\n\n- (void) copyLocalPath:(nonnull NSString *)localPath\n               smbPath:(nonnull NSString *)smbPath\n             overwrite:(BOOL)overwrite\n              progress:(nullable KxSMBBlockProgress)progress\n                 block:(nonnull KxSMBBlock)block;\n\n- (void) removeFolderAtPath:(nonnull NSString *)path\n                      block:(nonnull KxSMBBlock)block;\n\n- (void) renameAtPath:(nonnull NSString *)oldPath\n              newPath:(nonnull NSString *)newPath\n                block:(nonnull KxSMBBlock)block;\n\n@end\n\n@interface NSString (KxSMB)\n\n- (nonnull NSString *) stringByAppendingSMBPathComponent:(nonnull NSString *)aString;\n\n@end\n"
  },
  {
    "path": "KxSMBProvider.m",
    "content": "//\n//  KxSambaProvider.m\n//  kxsmb project\n//  https://github.com/kolyvan/kxsmb/\n//\n//  Created by Kolyvan on 28.03.13.\n//\n\n/*\n Copyright (c) 2013 Konstantin Bukreev All rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are met:\n \n - Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n \n - Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\n#import \"KxSMBProvider.h\"\n#import \"libsmbclient.h\"\n#import \"talloc_stack.h\"\n\n///////////////////////////////////////////////////////////////////////////////\n\nNSString * const KxSMBErrorDomain = @\"ru.kolyvan.KxSMB\";\n\nstatic NSString * KxSMBErrorMessage (KxSMBError errorCode)\n{\n    switch (errorCode) {\n        case KxSMBErrorUnknown:             return NSLocalizedString(@\"SMB Error\", nil);\n        case KxSMBErrorInvalidArg:          return NSLocalizedString(@\"SMB Invalid argument\", nil);\n        case KxSMBErrorInvalidProtocol:     return NSLocalizedString(@\"SMB Invalid protocol\", nil);\n        case KxSMBErrorOutOfMemory:         return NSLocalizedString(@\"SMB Out of memory\", nil);\n        case KxSMBErrorAccessDenied:        return NSLocalizedString(@\"SMB Access Denied\", nil);\n        case KxSMBErrorInvalidPath:         return NSLocalizedString(@\"SMB No such file or directory\", nil);\n        case KxSMBErrorPathIsNotDir:        return NSLocalizedString(@\"SMB Not a directory\", nil);\n        case KxSMBErrorPathIsDir:           return NSLocalizedString(@\"SMB Is a directory\", nil);\n        case KxSMBErrorWorkgroupNotFound:   return NSLocalizedString(@\"SMB Workgroup not found\", nil);\n        case KxSMBErrorShareDoesNotExist:   return NSLocalizedString(@\"SMB Share does not exist\", nil);\n        case KxSMBErrorItemAlreadyExists:   return NSLocalizedString(@\"SMB Item already exists\", nil);\n        case KxSMBErrorDirNotEmpty:         return NSLocalizedString(@\"SMB Directory not empty\", nil);\n        case KxSMBErrorFileIO:              return NSLocalizedString(@\"SMB File I/O failure\", nil);\n        case KxSMBErrorConnRefused:         return NSLocalizedString(@\"SMB Connection refused\", nil);\n        case KxSMBErrorOpNotPermited:       return NSLocalizedString(@\"SMB Operation not permitted\", nil);\n    }\n}\n\nstatic NSError * mkKxSMBError(KxSMBError error, NSString *format, ...)\n{\n    NSDictionary *userInfo = nil;\n    NSString *reason = nil;\n    \n    if (format) {\n        \n        va_list args;\n        va_start(args, format);\n        reason = [[NSString alloc] initWithFormat:format arguments:args];\n        va_end(args);\n    }\n    \n    if (reason) {\n        \n        userInfo = @{\n                     NSLocalizedDescriptionKey : KxSMBErrorMessage(error),\n                     NSLocalizedFailureReasonErrorKey : reason\n                     };\n        \n    } else {\n        \n        userInfo = @{ NSLocalizedDescriptionKey : KxSMBErrorMessage(error) };\n    }\n    \n    return [NSError errorWithDomain:KxSMBErrorDomain\n                               code:error\n                           userInfo:userInfo];\n}\n\nstatic KxSMBError errnoToSMBErr(int err)\n{\n    switch (err) {\n        case EINVAL:        return KxSMBErrorInvalidArg;\n        case ENOMEM:        return KxSMBErrorOutOfMemory;\n        case EACCES:        return KxSMBErrorAccessDenied;\n        case ENOENT:        return KxSMBErrorInvalidPath;\n        case ENOTDIR:       return KxSMBErrorPathIsNotDir;\n        case EISDIR:        return KxSMBErrorPathIsDir;\n        case EPERM:         return KxSMBErrorOpNotPermited;\n        case ENODEV:        return KxSMBErrorShareDoesNotExist;\n        case EEXIST:        return KxSMBErrorItemAlreadyExists;\n        case ENOTEMPTY:     return KxSMBErrorDirNotEmpty;\n        case ECONNREFUSED:  return KxSMBErrorConnRefused;\n        default:            return KxSMBErrorUnknown;\n    }    \n}\n\n///////////////////////////////////////////////////////////////////////////////\n\n@implementation KxSMBAuth\n\n+ (instancetype) smbAuthWorkgroup:(NSString *)workgroup\n                         username:(NSString *)username\n                         password:(NSString *)password\n{\n    KxSMBAuth *auth = [[KxSMBAuth alloc] init];\n    auth.workgroup = workgroup;\n    auth.username = username;\n    auth.password = password;\n    return auth;\n}\n\n@end\n\n///////////////////////////////////////////////////////////////////////////////\n\n@interface KxSMBItemStat ()\n@property(readwrite, nonatomic, strong) NSDate *lastModified;\n@property(readwrite, nonatomic, strong) NSDate *lastAccess;\n@property(readwrite, nonatomic, strong) NSDate *creationTime;\n@property(readwrite, nonatomic) SInt64 size;\n@property(readwrite, nonatomic) UInt16 mode;\n@end\n\n@implementation KxSMBItemStat\n@end\n\n@implementation KxSMBItem\n\n- (id) initWithType:(KxSMBItemType) type\n               path:(NSString *) path\n               stat:(KxSMBItemStat *)stat\n               auth:(KxSMBAuth *)auth\n{\n    self = [super init];\n    if (self) {\n        _type = type;\n        _path = path;\n        _stat = stat;\n        _auth = auth;\n    }\n    return self;\n}\n\n- (NSString *) description\n{\n    NSString *stype = @\"\";\n    \n    switch (_type) {\n            \n        case KxSMBItemTypeUnknown:   stype = @\"?\"; break;\n        case KxSMBItemTypeWorkgroup: stype = @\"group\"; break;\n        case KxSMBItemTypeServer:    stype = @\"server\"; break;\n        case KxSMBItemTypeFileShare: stype = @\"fileshare\"; break;\n        case KxSMBItemTypePrinter:   stype = @\"printer\"; break;\n        case KxSMBItemTypeComms:     stype = @\"comms\"; break;\n        case KxSMBItemTypeIPC:       stype = @\"ipc\"; break;\n        case KxSMBItemTypeDir:       stype = @\"dir\"; break;\n        case KxSMBItemTypeFile:      stype = @\"file\"; break;\n        case KxSMBItemTypeLink:      stype = @\"link\"; break;\n    }\n    \n    return [NSString stringWithFormat:@\"<smb %@ '%@' %lld>\",\n            stype, _path, _stat.size];\n}\n\n@end\n\n///////////////////////////////////////////////////////////////////////////////\n\nstatic void my_smbc_get_auth_data_fn(const char *srv,\n                                     const char *shr,\n                                     char *workgroup, int wglen,\n                                     char *username, int unlen,\n                                     char *password, int pwlen);\n\nstatic void my_smbc_get_auth_data_with_context_fn(SMBCCTX *c,\n                                                  const char *srv,\n                                                  const char *shr,\n                                                  char *wg, int wglen,\n                                                  char *un, int unlen,\n                                                  char *pw, int pwlen);\n\n///////////////////////////////////////////////////////////////////////////////\n\n\n@interface KxSMBItemFile()\n- (id) createFile:(BOOL)overwrite;\n@end\n\n///////////////////////////////////////////////////////////////////////////////\n\n\n@implementation KxSMBConfig\n\n- (id) init\n{\n    if ((self = [super init])) {\n        \n        _timeout                    = 10000; // ms\n#ifdef DEBUG\n        _debugLevel                 = 1;\n#else\n        _debugLevel                 = 0;\n#endif\n        _debugToStderr              = YES;\n        _fullTimeNames              = YES;\n        _shareMode                  = KxSMBConfigShareModeDenyNone;\n        _encryptionLevel            = KxSMBConfigEncryptLevelNone;\n        _caseSensitive              = NO;\n        _browseMaxLmbCount          = 3;\n        _urlEncodeReaddirEntries    = NO;\n        _oneSharePerServer          = NO;\n        _useKerberos                = NO;\n        _fallbackAfterKerberos      = YES;\n        _noAutoAnonymousLogin       = NO;\n        _useCCache                  = NO;\n        _useNTHash                  = NO;\n    }\n    return self;\n}\n\n- (void) configureSmbContext:(SMBCCTX *)smbContext\n{\n    smbc_setTimeout(smbContext,  (int)_timeout);\n    smbc_setDebug(smbContext, (int)_debugLevel);\n    \n    smbc_setOptionDebugToStderr(smbContext, (smbc_bool)_debugToStderr);\n    smbc_setOptionFullTimeNames(smbContext, (smbc_bool)_fullTimeNames);\n    smbc_setOptionOpenShareMode(smbContext, (smbc_share_mode)_shareMode);\n    smbc_setOptionSmbEncryptionLevel(smbContext, (smbc_smb_encrypt_level)_encryptionLevel);\n    smbc_setOptionCaseSensitive(smbContext, (smbc_bool)_caseSensitive);\n    smbc_setOptionBrowseMaxLmbCount(smbContext, (int)_browseMaxLmbCount);\n    smbc_setOptionUrlEncodeReaddirEntries(smbContext, (smbc_bool)_urlEncodeReaddirEntries);\n    smbc_setOptionOneSharePerServer(smbContext, (smbc_bool)_oneSharePerServer);\n    smbc_setOptionUseKerberos(smbContext, (smbc_bool)_useKerberos);\n    smbc_setOptionFallbackAfterKerberos(smbContext, (smbc_bool)_fallbackAfterKerberos);\n    smbc_setOptionNoAutoAnonymousLogin(smbContext, (smbc_bool)_noAutoAnonymousLogin);\n    smbc_setOptionUseCCache(smbContext, (smbc_bool)_useCCache);\n    smbc_setOptionUseNTHash(smbContext, (smbc_bool)_useNTHash);\n    \n    if (_netbiosName.length) {\n        smbc_setNetbiosName(smbContext, (char *)_netbiosName.UTF8String);\n    }\n    if (_workgroup.length) {\n        smbc_setWorkgroup(smbContext, (char *)_workgroup.UTF8String);\n    }\n    if (_username.length) {\n        smbc_setUser(smbContext, (char *)_username.UTF8String);\n    }\n}\n\n@end\n\n///////////////////////////////////////////////////////////////////////////////\n\nstatic KxSMBProvider *gSmbProvider;\n\n@interface KxSMBProvider ()\n@end\n\n@implementation KxSMBProvider {\n    \n    dispatch_queue_t _dispatchQueue;\n}\n\n+ (instancetype) sharedSmbProvider\n{\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        gSmbProvider = [[KxSMBProvider alloc] init];\n    });\n    return gSmbProvider;\n}\n\n- (id) init\n{\n    NSAssert(!gSmbProvider, @\"singleton object\");\n    \n    self = [super init];\n    if (self) {\n        \n        _config = [KxSMBConfig new];\n        _dispatchQueue  = dispatch_queue_create(\"KxSMBProvider\", DISPATCH_QUEUE_SERIAL);\n        _completionQueue = dispatch_get_main_queue();\n    }\n    return self;\n}\n\n- (void) dealloc\n{    \n    if (_dispatchQueue) {\n        #if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000\n        dispatch_release(_dispatchQueue);\n        #endif\n        _dispatchQueue = NULL;\n    }\n}\n\n#pragma mark - class methods\n\n+ (SMBCCTX *) openSmbContext:(KxSMBAuth *)auth\n{\n    //NSParameterAssert(auth);\n    \n    SMBCCTX *smbContext = smbc_new_context();\n    if (!smbContext) {\n\t\treturn NULL;\n    }\n    \n    if (auth) {\n        \n        smbc_setFunctionAuthDataWithContext(smbContext, my_smbc_get_auth_data_with_context_fn);\n        smbc_setOptionUserData(smbContext, (void *)CFBridgingRetain(auth));\n        \n    } else {\n        \n        smbc_setFunctionAuthData(smbContext, my_smbc_get_auth_data_fn);\n    }\n    \n    KxSMBConfig *cfg = [KxSMBProvider sharedSmbProvider].config;\n    [cfg configureSmbContext:smbContext];\n    \n\tif (!smbc_init_context(smbContext)) {\n        \n        void *userdata = smbc_getOptionUserData(smbContext);\n        if (userdata) {\n            CFBridgingRelease(userdata);\n        }\n        \n\t\tsmbc_free_context(smbContext, NO);\n\t\treturn NULL;\n\t}\n    \n    smbc_set_context(smbContext);\n    return smbContext;\n}\n\n+ (void) closeSmbContext:(SMBCCTX *)smbContext\n{\n    if (smbContext) {\n        \n        void *userdata = smbc_getOptionUserData(smbContext);\n        if (userdata) {\n            CFBridgingRelease(userdata);\n        }\n        \n        // fixes warning: no talloc stackframe at libsmb/cliconnect.c:2637, leaking memory\n        TALLOC_CTX *frame = talloc_stackframe();\n        smbc_getFunctionPurgeCachedServers(smbContext)(smbContext);\n        TALLOC_FREE(frame);\n        \n        smbc_free_context(smbContext, NO);\n    }\n}\n\n+ (id) fetchTreeAtPath:(NSString *)path\n                  auth:(KxSMBAuth *)auth\n{\n    NSParameterAssert(path);    \n    \n    SMBCCTX *smbContext = [self openSmbContext:auth];\n    if (!smbContext) {\n        const int err = errno;\n        return mkKxSMBError(errnoToSMBErr(err),\n                            NSLocalizedString(@\"Unable init SMB context (errno:%d)\", nil), err);\n    }\n    \n    id result = nil;\n    \n    SMBCFILE *smbFile = smbc_getFunctionOpendir(smbContext)(smbContext, path.UTF8String);\n    if (smbFile) {\n        \n        NSMutableArray *ma = [NSMutableArray array];\n        \n        struct smbc_dirent *dirent;\n        \n        smbc_readdir_fn readdirFn = smbc_getFunctionReaddir(smbContext);\n        \n        while((dirent = readdirFn(smbContext, smbFile)) != NULL) {\n            \n            if (!dirent->name) continue;\n            if (!strlen(dirent->name)) continue;\n            if (!strcmp(dirent->name, \".\") || !strcmp(dirent->name, \"..\") || !strcmp(dirent->name, \"IPC$\")) continue;\n            \n            NSString *name = [NSString stringWithUTF8String:dirent->name];\n            \n            NSString *itemPath;\n            if ([path characterAtIndex:path.length-1] == '/')\n                itemPath = [path stringByAppendingString:name] ;\n            else\n                itemPath = [NSString stringWithFormat:@\"%@/%@\", path, name];\n                        \n            KxSMBItemStat *stat = nil;\n            \n            if (dirent->smbc_type != SMBC_WORKGROUP &&\n                dirent->smbc_type != SMBC_SERVER) {\n                \n                id r = [self fetchStat:smbContext atPath:itemPath];\n                if ([r isKindOfClass:[KxSMBItemStat class]]) {\n                    stat = r;\n                }\n            }\n            \n            switch(dirent->smbc_type)\n            {\n                case SMBC_WORKGROUP:\n                case SMBC_SERVER: {\n                    KxSMBItem *item = [[KxSMBItemTree alloc] initWithType:dirent->smbc_type\n                                                                     path:[NSString stringWithFormat:@\"smb://%@\", name]\n                                                                     stat:nil\n                                                                     auth:auth];\n                    [ma addObject:item];\n                    break;\n                }\n                    \n                case SMBC_FILE_SHARE:\n                case SMBC_IPC_SHARE:\n                case SMBC_DIR: {\n                    KxSMBItem *item = [[KxSMBItemTree alloc] initWithType:dirent->smbc_type\n                                                                     path:itemPath\n                                                                     stat:stat\n                                                                     auth:auth];\n                    [ma addObject:item];\n                    break;\n                }\n                    \n                case SMBC_FILE: {\n                    KxSMBItem *item = [[KxSMBItemFile alloc] initWithType:KxSMBItemTypeFile\n                                                                     path:itemPath\n                                                                     stat:stat\n                                                                     auth:auth];\n                    [ma addObject:item];\n                    break;\n                }\n                    \n                case SMBC_PRINTER_SHARE:\n                case SMBC_COMMS_SHARE:\n                case SMBC_LINK: {\n                    KxSMBItem *item = [[KxSMBItem alloc] initWithType:dirent->smbc_type\n                                                                 path:itemPath\n                                                                 stat:stat\n                                                                 auth:auth];\n                    [ma addObject:item];\n                    break;\n                }\n            }\n        }\n        \n        smbc_getFunctionClose(smbContext)(smbContext, smbFile);        \n        result = [ma copy];\n        \n    } else {\n        \n        const int err = errno;\n        result = mkKxSMBError(errnoToSMBErr(err),\n                              NSLocalizedString(@\"Unable open dir:%@ (errno:%d)\", nil), path, err);\n    }\n    \n    [self closeSmbContext:smbContext];\n    return result;\n}\n\n+ (id) fetchStat:(SMBCCTX *)smbContext\n          atPath:(NSString *)path\n{\n    NSParameterAssert(smbContext);\n    NSParameterAssert(path);\n    \n    struct stat st;\n    int r = smbc_getFunctionStat(smbContext)(smbContext, path.UTF8String, &st);\n    if (r < 0) {\n\n        const int err = errno;\n        return mkKxSMBError(errnoToSMBErr(err),\n                            NSLocalizedString(@\"Unable get stat:%@ (errno:%d)\", nil), path, err);\n    }\n    \n    KxSMBItemStat *stat = [[KxSMBItemStat alloc] init];\n    stat.lastModified = [NSDate dateWithTimeIntervalSince1970: st.st_mtime];\n    stat.lastAccess = [NSDate dateWithTimeIntervalSince1970: st.st_atime];\n    stat.creationTime = [NSDate dateWithTimeIntervalSince1970: st.st_ctime];\n    stat.size = st.st_size;\n    stat.mode = st.st_mode;    \n    return stat;\n    \n}\n\n+ (id) fetchAtPath:(NSString *)path\n         expandDir:(BOOL)expandDir\n              auth:(KxSMBAuth *)auth\n{\n    NSParameterAssert(path);\n    \n    if (![path hasPrefix:@\"smb://\"]) {\n        return mkKxSMBError(KxSMBErrorInvalidProtocol,\n                            NSLocalizedString(@\"Path:%@\", nil), path);\n    }\n\n    NSString *sPath = [path substringFromIndex:@\"smb://\".length];\n    \n    if (!sPath.length) {\n        return [self fetchTreeAtPath:path auth:auth];\n    }\n\n    if ([sPath hasSuffix:@\"/\"]) {\n        sPath = [sPath substringToIndex:sPath.length - 1];\n    }\n    \n    if (sPath.pathComponents.count == 1) {\n \n        // smb:// or smb://server/ or smb://workgroup/\n        return [self fetchTreeAtPath:path auth:auth];\n    }\n    \n    id result = nil;\n    \n    SMBCCTX *smbContext = [self openSmbContext:auth];\n    if (!smbContext) {\n        const int err = errno;\n        return mkKxSMBError(errnoToSMBErr(err),\n                            NSLocalizedString(@\"Unable init SMB context (errno:%d)\", nil), err);\n    }\n    \n    result = [self fetchStat:smbContext atPath:path];\n    \n    if ([result isKindOfClass:[KxSMBItemStat class]]) {\n        \n        KxSMBItemStat *stat = result;\n        \n        if (S_ISDIR(stat.mode)) {\n            \n            if (expandDir) {\n                \n                result = [self fetchTreeAtPath:path auth:auth];\n                \n            } else {\n                \n                result = [[KxSMBItemTree alloc] initWithType:KxSMBItemTypeDir\n                                                        path:path\n                                                        stat:stat\n                                                        auth:auth];\n            }\n            \n        } else if (S_ISREG(stat.mode)) {\n            \n            result = [[KxSMBItemFile alloc] initWithType:KxSMBItemTypeFile\n                                                    path:path\n                                                    stat:stat\n                                                    auth:auth];\n            \n        } else {\n            \n            result = [[KxSMBItem alloc] initWithType:S_ISLNK(stat.mode) ? KxSMBItemTypeLink : KxSMBItemTypeUnknown\n                                                path:path\n                                                stat:stat\n                                                auth:auth];\n        }\n    }\n    \n    [self closeSmbContext:smbContext];\n    return result;\n}\n\n+ (id) removeAtPath:(NSString *)path\n               auth:(KxSMBAuth *)auth\n{\n    NSParameterAssert(path);\n    \n    if (![path hasPrefix:@\"smb://\"]) {\n        return mkKxSMBError(KxSMBErrorInvalidProtocol,\n                            NSLocalizedString(@\"Path:%@\", nil), path);\n    }\n    \n    SMBCCTX *smbContext = [self openSmbContext:auth];\n    if (!smbContext) {\n        const int err = errno;\n        return mkKxSMBError(errnoToSMBErr(err),\n                            NSLocalizedString(@\"Unable init SMB context (errno:%d)\", nil), err);\n    }\n\n    id result;    \n    \n    int r = smbc_getFunctionUnlink(smbContext)(smbContext, path.UTF8String);\n    if (r < 0) {\n        \n        int err = errno;\n        if (err == EISDIR || err == EINVAL) {\n            \n            r = smbc_getFunctionRmdir(smbContext)(smbContext, path.UTF8String);\n            if (r < 0) {\n                \n                err = errno;\n                result =  mkKxSMBError(errnoToSMBErr(err),\n                                       NSLocalizedString(@\"Unable rmdir file:%@ (errno:%d)\", nil), path, err);\n            }\n            \n        } else {\n            \n            result =  mkKxSMBError(errnoToSMBErr(err),\n                                   NSLocalizedString(@\"Unable unlink file:%@ (errno:%d)\", nil), path, err);\n            \n        }\n        \n    }\n    \n    [self closeSmbContext:smbContext];\n    return result;\n}\n\n+ (id) createFolderAtPath:(NSString *)path\n                     auth:(KxSMBAuth *)auth\n{\n    NSParameterAssert(path);\n    \n    if (![path hasPrefix:@\"smb://\"]) {\n        return mkKxSMBError(KxSMBErrorInvalidProtocol,\n                            NSLocalizedString(@\"Path:%@\", nil), path);\n    }\n    \n    SMBCCTX *smbContext = [self openSmbContext:auth];\n    if (!smbContext) {\n        const int err = errno;\n        return mkKxSMBError(errnoToSMBErr(err),\n                            NSLocalizedString(@\"Unable init SMB context (errno:%d)\", nil), err);\n    }\n    \n    id result;\n    \n    int r = smbc_getFunctionMkdir(smbContext)(smbContext, path.UTF8String, 0);\n    if (r < 0) {\n        \n        const int err = errno;\n        result =  mkKxSMBError(errnoToSMBErr(err),\n                               NSLocalizedString(@\"Unable mkdir:%@ (errno:%d)\", nil), path, err);\n        \n    } else {\n        \n        id stat = [self fetchStat:smbContext atPath: path];\n        if ([stat isKindOfClass:[KxSMBItemStat class]]) {\n            \n            result = [[KxSMBItemTree alloc] initWithType:KxSMBItemTypeDir\n                                                    path:path\n                                                    stat:stat\n                                                    auth:auth];\n            \n        } else {\n            \n            result = stat;\n        }\n    }\n    \n    [self closeSmbContext:smbContext];\n    return result;\n}\n\n+ (id) createFileAtPath:(NSString *)path\n              overwrite:(BOOL)overwrite\n                   auth:(KxSMBAuth *)auth\n{\n    NSParameterAssert(path);\n    \n    if (![path hasPrefix:@\"smb://\"]) {\n        return mkKxSMBError(KxSMBErrorInvalidProtocol,\n                            NSLocalizedString(@\"Path:%@\", nil), path);\n    }\n    \n    KxSMBItemFile *itemFile =  [[KxSMBItemFile alloc] initWithType:KxSMBItemTypeFile\n                                                              path:path\n                                                              stat:nil\n                                                              auth:auth];\n    id result = [itemFile createFile:overwrite];\n    if ([result isKindOfClass:[NSError class]]) {\n        return result;\n    }\n    return itemFile;\n}\n\n+ (NSError *) ensureLocalFolderExists:(NSString *)folderPath\n{\n    NSFileManager *fm = [[NSFileManager alloc] init];\n    BOOL isDir;\n    if ([fm fileExistsAtPath:folderPath isDirectory:&isDir]) {\n        \n        if (!isDir) {\n            \n            return mkKxSMBError(KxSMBErrorFileIO,\n                                NSLocalizedString(@\"Cannot overwrite file %@\", nil),\n                                folderPath);\n        }\n        \n    } else {\n        \n        NSError *error;\n        if (![fm createDirectoryAtPath:folderPath\n           withIntermediateDirectories:NO\n                            attributes:nil\n                                 error:&error]) {\n            \n            return error;\n            \n        }\n    }\n    return nil;\n}\n\n+ (NSFileHandle *) createLocalFile:(NSString *)path\n                         overwrite:(BOOL) overwrite\n                             error:(NSError **)outError\n{\n    NSFileManager *fm = [[NSFileManager alloc] init];\n    \n    if ([fm fileExistsAtPath:path]) {\n        \n        if (overwrite) {\n            \n            if (![fm removeItemAtPath:path error:outError]) {\n                return nil;\n            }\n            \n        } else {\n            \n            return nil;\n        }\n    }\n    \n    NSString *folder = path.stringByDeletingLastPathComponent;\n    \n    if (![fm fileExistsAtPath:folder] &&\n        ![fm createDirectoryAtPath:folder\n       withIntermediateDirectories:YES\n                        attributes:nil\n                             error:outError]) {\n            return nil;\n        }\n    \n    if (![fm createFileAtPath:path\n                     contents:nil\n                   attributes:nil]) {\n        \n        if (outError) {\n            *outError = mkKxSMBError(KxSMBErrorFileIO,\n                                     NSLocalizedString(@\"Unable create file\", nil),\n                                     path.lastPathComponent);\n        }\n        return nil;\n    }\n    \n    return [NSFileHandle fileHandleForWritingToURL:[NSURL fileURLWithPath:path]\n                                             error:outError];\n}\n\n+ (void) readSMBFile:(KxSMBItemFile *)smbFile\n          fileHandle:(NSFileHandle *)fileHandle\n            progress:(KxSMBBlockProgress)progress\n               block:(KxSMBBlock)block\n{\n    [smbFile readDataOfLength:1024*1024\n                        block:^(id result)\n     {\n         if ([result isKindOfClass:[NSData class]]) {\n             \n             NSData *data = result;\n             if (data.length) {\n                 \n                 [fileHandle writeData:data];\n                 \n                 if (progress) {\n                     \n                     BOOL stop = NO;\n                     progress(smbFile, fileHandle.offsetInFile, &stop);\n                     if (stop) {\n                         \n                         // remove the local file from a disk\n                         NSString *filePath;\n                         char buffer[PATH_MAX] = {0};\n                         if (fcntl(fileHandle.fileDescriptor, F_GETPATH, buffer) != -1) {\n                             filePath = [[NSString alloc] initWithUTF8String:buffer];\n                         }\n                         //[fileHandle truncateFileAtOffset:0];\n                         [fileHandle closeFile];\n                         if (filePath.length) {\n                             [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];\n                         }\n                         \n                         block(nil);\n                         return;\n                     }\n                 }\n                 \n                 [self readSMBFile:smbFile\n                        fileHandle:fileHandle\n                          progress:progress\n                             block:block];\n                 \n             } else {\n                 \n                 [fileHandle closeFile];\n                 block(@(YES)); // complete\n             }\n             \n             return;\n         }\n         \n         [fileHandle closeFile];\n         block([result isKindOfClass:[NSError class]] ? result : nil);\n     }];\n    \n}\n\n+ (void) copySMBFile:(KxSMBItemFile *)smbFile\n           localPath:(NSString *)localPath\n           overwrite:(BOOL)overwrite\n            progress:(KxSMBBlockProgress)progress\n               block:(KxSMBBlock)block\n{\n    NSError *error = nil;\n    NSFileHandle *fileHandle = [self createLocalFile:localPath overwrite:overwrite error:&error];\n    if (fileHandle) {\n        \n        [self readSMBFile:smbFile\n               fileHandle:fileHandle\n                 progress:progress\n                    block:block];\n        \n    } else {\n        \n        if (!error) {\n            \n            error = mkKxSMBError(KxSMBErrorFileIO,\n                                 NSLocalizedString(@\"Cannot overwrite file %@\", nil),\n                                 localPath.lastPathComponent);\n        }\n        \n        block(error);\n    }\n}\n\n+ (void) enumerateSMBFolders:(NSArray *)folders\n                       items:(NSMutableArray *)items\n                       block:(KxSMBBlock)block\n{\n    KxSMBItemTree *folder = folders[0];\n    NSMutableArray *mfolders = [folders mutableCopy];\n    [mfolders removeObjectAtIndex:0];\n    \n    [folder fetchItems:^(id result)\n     {\n         if ([result isKindOfClass:[NSArray class]]) {\n             \n             for (KxSMBItem *item in result ) {\n                 \n                 if ([item isKindOfClass:[KxSMBItemFile class]]) {\n                     \n                     [items addObject:item];\n                     \n                 } else if ([item isKindOfClass:[KxSMBItemTree class]] &&\n                            (item.type == KxSMBItemTypeDir ||\n                             item.type == KxSMBItemTypeFileShare ||\n                             item.type == KxSMBItemTypeServer))\n                 {\n                     [mfolders addObject:item];\n                     [items addObject:item];\n                 }\n             }\n             \n             if (mfolders.count) {\n                 \n                 [self enumerateSMBFolders:mfolders items:items block:block];\n                 \n             } else {\n                 \n                 block(items);\n             }\n             \n         } else {\n             \n             block([result isKindOfClass:[NSError class]] ? result : nil);\n         }\n     }];\n}\n\n+ (void) copySMBItems:(NSArray *)smbItems\n            smbFolder:(NSString *)smbFolder\n          localFolder:(NSString *)localFolder\n            overwrite:(BOOL)overwrite\n             progress:(KxSMBBlockProgress)progress\n                block:(KxSMBBlock)block\n{\n    KxSMBItem *item = smbItems[0];\n    if (smbItems.count > 1) {\n        smbItems = [smbItems subarrayWithRange:NSMakeRange(1, smbItems.count - 1)];\n    } else {\n        smbItems = nil;\n    }\n    \n    if ([item isKindOfClass:[KxSMBItemFile class]]) {\n        \n        NSString *destPath = localFolder;\n        NSString *itemFolder = item.path.stringByDeletingLastPathComponent;\n        if (itemFolder.length > smbFolder.length) {\n            NSString *relPath = [itemFolder substringFromIndex:smbFolder.length];\n            destPath = [destPath stringByAppendingPathComponent:relPath];\n        }\n        destPath = [destPath stringByAppendingSMBPathComponent:item.path.lastPathComponent];\n        \n        [self copySMBFile:(KxSMBItemFile *)item\n                 localPath:destPath\n                overwrite:overwrite\n                 progress:progress\n                    block:^(id result)\n         {\n             if ([result isKindOfClass:[NSError class]]) {\n                 \n                 block(result);\n                 \n             } else {\n                 \n                 if (smbItems.count) {\n                     \n                     [self copySMBItems:smbItems\n                              smbFolder:smbFolder\n                            localFolder:localFolder\n                              overwrite:overwrite\n                               progress:progress\n                                  block:block];\n                     \n                 } else {\n                     \n                     block(@(YES)); // complete\n                 }\n             }             \n         }];\n        \n    } else if ([item isKindOfClass:[KxSMBItemTree class]]) {\n        \n        NSString *destPath = localFolder;\n        NSString *itemFolder = item.path;\n        if (itemFolder.length > smbFolder.length) {\n            NSString *relPath = [itemFolder substringFromIndex:smbFolder.length];\n            destPath = [destPath stringByAppendingPathComponent:relPath];\n        }\n        \n        NSError *error = [self ensureLocalFolderExists:destPath];\n        if (error) {\n            block(error);\n            return;\n        }\n        \n        if (smbItems.count) {\n            \n            [self copySMBItems:smbItems\n                     smbFolder:smbFolder\n                   localFolder:localFolder\n                     overwrite:overwrite\n                      progress:progress\n                         block:block];\n            \n        } else {\n            \n            block(@(YES)); // complete\n        }\n    }\n}\n\n///\n\n+ (void) writeSMBFile:(KxSMBItemFile *)smbFile\n           fileHandle:(NSFileHandle *)fileHandle\n             progress:(KxSMBBlockProgress)progress\n                block:(KxSMBBlock)block\n{\n    NSData *data;\n    \n    @try {\n        \n        data = [fileHandle readDataOfLength:1024*1024];\n    }\n    @catch (NSException *exception) {\n        \n        [fileHandle closeFile];\n        block(mkKxSMBError(KxSMBErrorFileIO, [exception description]));\n        return;\n    }\n    \n    if (data.length) {\n        \n        [smbFile writeData:data block:^(id result) {\n            \n            if ([result isKindOfClass:[NSNumber class]]) {\n                \n                if (progress) {\n                    \n                    BOOL stop = NO;\n                    progress(smbFile, fileHandle.offsetInFile, &stop);\n                    if (stop) {\n                        \n                        [fileHandle closeFile];\n                        \n                        // remove the smbfile from a share\n                        NSString *smbPath = smbFile.path;\n                        [smbFile close];\n                        KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n                        [provider dispatchAsync:^{\n                            [KxSMBProvider removeAtPath:smbPath auth:smbFile.auth];\n                        }];\n                        \n                        block(nil);\n                        return;\n                    }\n                }\n                \n                [self  writeSMBFile:smbFile\n                         fileHandle:fileHandle\n                           progress:progress\n                              block:block];\n                \n                return;\n            }\n            \n            block([result isKindOfClass:[NSError class]] ? result : nil);\n        }];\n        \n    } else {\n        \n        [fileHandle closeFile];\n        block(smbFile);\n    }\n}\n\n+ (void) copyLocalFile:(NSString *)localPath\n               smbPath:(NSString *)smbPath\n             overwrite:(BOOL)overwrite\n                  auth:(KxSMBAuth *)auth\n              progress:(KxSMBBlockProgress)progress\n                 block:(KxSMBBlock)block\n{\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    \n    [provider createFileAtPath:smbPath\n                     overwrite:overwrite\n                          auth:auth\n                         block:^(id result)\n     {\n         if ([result isKindOfClass:[KxSMBItemFile class]]) {\n             \n             NSError *error = nil;\n             NSFileHandle *fileHandle;\n             NSURL *url =[NSURL fileURLWithPath:localPath];\n             fileHandle = [NSFileHandle fileHandleForReadingFromURL:url error:&error];\n             \n             if (fileHandle) {\n                 \n                 [self writeSMBFile:result\n                         fileHandle:fileHandle\n                           progress:progress\n                              block:block];\n                 \n             } else {\n                 \n                 block(error);\n             }\n             \n         } else {\n             \n             block([result isKindOfClass:[NSError class]] ? result : nil);\n         }\n     }];\n}\n\n+ (void) copyLocalFiles:(NSDirectoryEnumerator *)enumerator\n            localFolder:(NSString *)localFolder\n              smbFolder:(KxSMBItemTree *)smbFolder\n              overwrite:(BOOL)overwrite\n               progress:(KxSMBBlockProgress)progress\n                  block:(KxSMBBlock)block\n{\n    NSString *path = [enumerator nextObject];\n    if (path) {\n        \n        if (path.length && [path characterAtIndex:0] != '.') {\n            \n            NSDictionary *attr = [enumerator fileAttributes];\n            if ([[attr fileType] isEqualToString:NSFileTypeDirectory]) {\n                \n                KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n                [provider createFolderAtPath:[smbFolder.path stringByAppendingSMBPathComponent:path]\n                                        auth:smbFolder.auth\n                                       block:^(id result)\n                 {\n                     if ([result isKindOfClass:[NSError class]]) {\n                         \n                         block(result);\n                         \n                     } else {\n                         \n                         [self copyLocalFiles:enumerator\n                                  localFolder:localFolder\n                                    smbFolder:smbFolder\n                                    overwrite:overwrite\n                                     progress:progress\n                                        block:block];\n                     }\n                 }];\n                \n                return;\n                \n            } else if ([[attr fileType] isEqualToString:NSFileTypeRegular]) {\n                \n                NSString *destFolder = smbFolder.path;\n                NSString *fileFolder = path.stringByDeletingLastPathComponent;\n                if (fileFolder.length) {\n                    destFolder = [destFolder stringByAppendingSMBPathComponent:fileFolder];\n                }\n                \n                [self copyLocalFile:[localFolder stringByAppendingPathComponent:path]\n                            smbPath:[destFolder stringByAppendingSMBPathComponent:path.lastPathComponent]\n                          overwrite:overwrite\n                               auth:smbFolder.auth\n                           progress:progress\n                              block:^(id result)\n                 {\n                     if ([result isKindOfClass:[NSError class]]) {\n                         \n                         block(result);\n                         \n                     } else {\n                         \n                         [self copyLocalFiles:enumerator\n                                  localFolder:localFolder\n                                    smbFolder:smbFolder\n                                    overwrite:overwrite\n                                     progress:progress\n                                        block:block];\n                     }\n                 }];\n                \n                return;\n            }\n        }\n        \n        [self copyLocalFiles:enumerator\n                 localFolder:localFolder\n                   smbFolder:smbFolder\n                   overwrite:overwrite\n                    progress:progress\n                       block:block];\n        \n    } else {\n        \n        block(smbFolder);\n    }\n}\n\n+ (void) copyFileFromPath:(NSString *)oldPath\n                   toPath:(NSString *)newPath\n                overwrite:(BOOL)overwrite\n                     auth:(KxSMBAuth *)auth\n                 progress:(KxSMBBlockProgress)progress\n                    block:(KxSMBBlock)block\n{\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    \n    [provider fetchAtPath:oldPath\n                expandDir:NO\n                     auth:auth\n                    block:^(id result)\n    {\n        if ([result isKindOfClass:[KxSMBItemFile class]]) {\n            \n            KxSMBItemFile *fromFile = result;\n            \n            [provider createFileAtPath:newPath\n                             overwrite:overwrite\n                                  auth:auth\n                                 block:^(id result)\n             {\n                 if ([result isKindOfClass:[KxSMBItemFile class]]) {\n                     \n                     KxSMBItemFile *toFile = result;\n                     \n                     [self copyFromSMBFile:fromFile\n                                 toSMBFile:toFile\n                                  progress:progress\n                                     block:block];\n                 } else {\n                     \n                     block([result isKindOfClass:[NSError class]] ? result : nil);\n                 }\n             }];\n            \n        } else if ([result isKindOfClass:[KxSMBItemTree class]]) {\n        \n            block(mkKxSMBError(KxSMBErrorPathIsDir, newPath, 0));\n            \n        } else {\n            \n            block([result isKindOfClass:[NSError class]] ? result : nil);\n        }\n    }];\n}\n\n+ (void) copyFromSMBFile:(KxSMBItemFile *)fromFile\n               toSMBFile:(KxSMBItemFile *)toFile\n                progress:(KxSMBBlockProgress)progress\n                   block:(KxSMBBlock)block\n{\n    [fromFile readDataOfLength:1024*1024\n                         block:^(id result)\n     {\n         if ([result isKindOfClass:[NSData class]]) {\n             \n             NSData *data = result;\n             if (data.length) {\n                 \n                 [toFile writeData:data block:^(id result) {\n                     \n                     if ([result isKindOfClass:[NSNumber class]]) {\n                         \n                         if (progress) {\n                             \n                             BOOL stop = NO;\n                             progress(fromFile, 0, &stop);\n                             if (stop) {\n                                 \n                                 // remove the dest smbfile from a share\n                                 NSString *smbPath = toFile.path;\n                                 [toFile close];\n                                 KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n                                 [provider dispatchAsync:^{\n                                     [KxSMBProvider removeAtPath:smbPath auth:toFile.auth];\n                                 }];\n                                 \n                                 block(nil);\n                                 return;\n                             }\n                         }\n                         \n                         [self copyFromSMBFile:fromFile\n                                     toSMBFile:toFile\n                                      progress:progress\n                                         block:block];\n                         \n                         return;\n                     }\n                     \n                     block([result isKindOfClass:[NSError class]] ? result : nil);\n                 }];\n                 \n             } else {\n                 \n                 block(toFile); // complete\n             }\n             \n             return;\n         }\n         \n         block([result isKindOfClass:[NSError class]] ? result : nil);\n     }];\n}\n\n///\n\n+ (void) removeSMBItems:(NSArray *)smbItems\n                  block:(KxSMBBlock)block\n{\n    KxSMBItem *item = smbItems[0];\n    if (smbItems.count > 1) {\n        smbItems = [smbItems subarrayWithRange:NSMakeRange(1, smbItems.count - 1)];\n    } else {\n        smbItems = nil;\n    }\n    \n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    [provider removeAtPath:item.path\n                      auth:item.auth\n                     block:^(id result) {\n      \n        if ([result isKindOfClass:[NSError class]]) {\n            \n            block(result);\n            \n        } else if (smbItems.count) {\n            \n            [self removeSMBItems:smbItems block:block];\n            \n        } else {\n            \n            block(@(YES));\n        }\n    }];\n}\n\n+ (id) renameAtPath:(NSString *)oldPath\n            newPath:(NSString *)newPath\n               auth:(KxSMBAuth *)auth\n{\n    NSParameterAssert(oldPath);\n    NSParameterAssert(newPath);    \n    \n    if (![oldPath hasPrefix:@\"smb://\"]) {\n        return mkKxSMBError(KxSMBErrorInvalidProtocol,\n                            NSLocalizedString(@\"Path:%@\", nil), oldPath);\n    }\n    \n    if (![newPath hasPrefix:@\"smb://\"]) {\n        return mkKxSMBError(KxSMBErrorInvalidProtocol,\n                            NSLocalizedString(@\"Path:%@\", nil), newPath);\n    }\n    \n    SMBCCTX *smbContext = [self openSmbContext:auth];\n    if (!smbContext) {\n        const int err = errno;\n        return mkKxSMBError(errnoToSMBErr(err),\n                            NSLocalizedString(@\"Unable init SMB context (errno:%d)\", nil), err);\n    }\n    \n    id result;\n    \n    int r = smbc_getFunctionRename(smbContext)(smbContext, oldPath.UTF8String, smbContext, newPath.UTF8String);\n    if (r < 0) {\n        \n        const int err = errno;\n        result =  mkKxSMBError(errnoToSMBErr(err),\n                               NSLocalizedString(@\"Unable rename file:%@ (errno:%d)\", nil), oldPath, err);\n        \n    } else {\n        \n        result = [self fetchStat:smbContext atPath: newPath];\n        if ([result isKindOfClass:[KxSMBItemStat class]]) {\n            \n            KxSMBItemStat *stat = result;\n            \n            if (S_ISDIR(stat.mode)) {\n                \n                result = [[KxSMBItemTree alloc] initWithType:KxSMBItemTypeDir\n                                                        path:newPath\n                                                        stat:stat\n                                                        auth:auth];\n                \n            } else if (S_ISREG(stat.mode)) {\n                \n                result = [[KxSMBItemFile alloc] initWithType:KxSMBItemTypeFile\n                                                        path:newPath\n                                                        stat:stat\n                                                        auth:auth];\n                \n            } else {\n                \n                result = nil;\n            }\n        } \n    }\n    \n    [self closeSmbContext:smbContext];\n    return result;\n}\n\n+ (void) fireBlock:(KxSMBBlock)block withResult:(id)result\n{\n    dispatch_queue_t queue = [KxSMBProvider sharedSmbProvider].completionQueue;\n    if (queue) {\n        dispatch_async(queue, ^{ block(result); });\n    } else {\n        block(result);\n    }\n}\n\n#pragma mark - internal methods\n\n- (void) dispatchSync: (dispatch_block_t) block\n{\n    dispatch_sync(_dispatchQueue, block);\n}\n\n- (void) dispatchAsync: (dispatch_block_t) block\n{\n    dispatch_async(_dispatchQueue, block);\n}\n\n#pragma mark - public methods\n\n- (void) fetchAtPath:(NSString *)path\n           expandDir:(BOOL)expandDir\n                auth:(KxSMBAuth *)auth\n               block:(KxSMBBlock)block\n{\n    NSParameterAssert(path);\n    NSParameterAssert(block);\n        \n    dispatch_async(_dispatchQueue, ^{\n                \n        id result = [KxSMBProvider fetchAtPath:(path.length ? path : @\"smb://\")\n                                     expandDir:expandDir\n                                          auth:auth];\n        [KxSMBProvider fireBlock:block withResult:result];\n    });\n}\n\n- (void) fetchAtPath:(NSString *)path\n                auth:(KxSMBAuth *)auth\n               block:(KxSMBBlock)block\n{\n    [self fetchAtPath:path\n            expandDir:YES\n                 auth:auth\n                block:block];\n}\n\n- (id) fetchAtPath:(NSString *)path\n         expandDir:(BOOL)expandDir\n              auth:(KxSMBAuth *)auth\n{\n    NSParameterAssert(path);\n    \n    __block id result = nil;\n    dispatch_sync(_dispatchQueue, ^{\n        \n        result = [KxSMBProvider fetchAtPath:(path.length ? path : @\"smb://\")\n                                  expandDir:expandDir\n                                       auth:auth];\n    });\n    return result;\n}\n\n- (id) fetchAtPath:(NSString *)path\n              auth:(KxSMBAuth *)auth\n{\n    return [self fetchAtPath:path expandDir:YES auth:auth];\n}\n\n- (void) createFileAtPath:(NSString *)path\n                overwrite:(BOOL)overwrite\n                     auth:(KxSMBAuth *)auth\n                    block:(KxSMBBlock) block\n{\n    NSParameterAssert(path);\n    NSParameterAssert(block);\n    \n    dispatch_async(_dispatchQueue, ^{\n        \n        id result = [KxSMBProvider createFileAtPath:path overwrite:overwrite auth:auth];\n        [KxSMBProvider fireBlock:block withResult:result];\n    });\n}\n\n- (id) createFileAtPath:(NSString *)path\n              overwrite:(BOOL)overwrite\n                   auth:(KxSMBAuth *)auth\n{\n    NSParameterAssert(path);\n    \n    __block id result = nil;\n    dispatch_sync(_dispatchQueue, ^{\n        result = [KxSMBProvider createFileAtPath:path overwrite:overwrite auth:auth];\n    });\n    return result;\n}\n\n- (void) removeAtPath:(NSString *)path\n                 auth:(KxSMBAuth *)auth\n                block:(KxSMBBlock)block\n{\n    NSParameterAssert(path);\n    NSParameterAssert(block);\n    \n    dispatch_async(_dispatchQueue, ^{\n        \n        id result = [KxSMBProvider removeAtPath:path auth:auth];\n        [KxSMBProvider fireBlock:block withResult:result];\n    });\n}\n\n- (id) removeAtPath:(NSString *)path\n               auth:(KxSMBAuth *)auth\n{\n    NSParameterAssert(path);\n    \n    __block id result = nil;\n    dispatch_sync(_dispatchQueue, ^{\n        result = [KxSMBProvider removeAtPath:path auth:auth];\n    });\n    return result;\n}\n\n- (void) createFolderAtPath:(NSString *)path\n                       auth:(KxSMBAuth *)auth\n                      block:(KxSMBBlock)block\n{\n    NSParameterAssert(path);\n    NSParameterAssert(block);\n    \n    dispatch_async(_dispatchQueue, ^{\n        \n        id result = [KxSMBProvider createFolderAtPath:path auth:auth];\n        [KxSMBProvider fireBlock:block withResult:result];\n    });\n}\n\n- (id) createFolderAtPath:(NSString *)path\n                     auth:(KxSMBAuth *)auth\n{\n    NSParameterAssert(path);\n    \n    __block id result = nil;\n    dispatch_sync(_dispatchQueue, ^{\n        result = [KxSMBProvider createFolderAtPath:path auth:auth];\n    });\n    return result;\n}\n\n- (void) copySMBPath:(NSString *)smbPath\n           localPath:(NSString *)localPath\n           overwrite:(BOOL)overwrite\n                auth:(KxSMBAuth *)auth\n               block:(KxSMBBlock)block\n{\n    [self copySMBPath:smbPath localPath:localPath overwrite:overwrite auth:auth progress:nil block:block];;\n}\n\n- (void) copyLocalPath:(NSString *)localPath\n               smbPath:(NSString *)smbPath\n             overwrite:(BOOL)overwrite\n                  auth:(KxSMBAuth *)auth\n                 block:(KxSMBBlock)block\n{\n    [self copyLocalPath:localPath smbPath:smbPath overwrite:overwrite auth:auth progress:nil block:block];\n}\n\n- (void) copySMBPath:(NSString *)smbPath\n           localPath:(NSString *)localPath\n           overwrite:(BOOL)overwrite\n                auth:(KxSMBAuth *)auth\n            progress:(KxSMBBlockProgress)progress\n               block:(KxSMBBlock)block\n{   \n    [self fetchAtPath:smbPath\n            expandDir:YES\n                 auth:auth\n                block:^(id result) {\n        \n        if ([result isKindOfClass:[KxSMBItemFile class]]) {\n            \n            [KxSMBProvider copySMBFile:result\n                             localPath:localPath\n                             overwrite:overwrite\n                              progress:progress\n                                 block:block];            \n            \n        } else if ([result isKindOfClass:[NSArray class]]) {\n            \n            NSError *error = [KxSMBProvider ensureLocalFolderExists:localPath];\n            if (error) {\n                block(error);\n                return;\n            }\n            \n            NSMutableArray *folders = [NSMutableArray array];\n            NSMutableArray *items = [NSMutableArray array];\n            \n            for (KxSMBItem *item in result ) {\n                \n                if ([item isKindOfClass:[KxSMBItemFile class]]) {\n                    \n                    [items addObject:item];\n                    \n                } else if ([item isKindOfClass:[KxSMBItemTree class]] &&\n                           (item.type == KxSMBItemTypeDir ||\n                            item.type == KxSMBItemTypeFileShare ||\n                            item.type == KxSMBItemTypeServer))\n                {\n                    [items addObject:item];\n                    [folders addObject:item];\n                }\n            }\n            \n            if (folders.count) {\n                \n                [KxSMBProvider enumerateSMBFolders:folders\n                                             items:items\n                                             block:^(id result)\n                 {                     \n                     if ([result isKindOfClass:[NSArray class]]) {\n                         \n                         NSArray *items = result;\n                         if (items.count) {\n                             \n                             [KxSMBProvider copySMBItems:items\n                                               smbFolder:smbPath\n                                             localFolder:localPath\n                                               overwrite:overwrite\n                                                progress:progress\n                                                   block:block];\n                             \n                         } else {\n                             \n                             block(@(YES));\n                         }\n                         \n                     } else {\n                         \n                         block(result);\n                     }\n                 }];\n                \n            } else if (items.count) {\n                \n                [KxSMBProvider copySMBItems:items\n                                  smbFolder:smbPath\n                                localFolder:localPath\n                                  overwrite:overwrite\n                                   progress:progress\n                                      block:block];                \n                \n            }  else {\n                \n                block(@(YES));\n                return;\n            }\n            \n        } else {\n            \n            block([result isKindOfClass:[NSError class]] ? result : nil);\n        }\n    }];\n}\n\n- (void) copyLocalPath:(NSString *)localPath\n               smbPath:(NSString *)smbPath\n             overwrite:(BOOL)overwrite\n                  auth:(KxSMBAuth *)auth\n              progress:(KxSMBBlockProgress)progress\n                 block:(KxSMBBlock)block\n{\n    NSFileManager *fm = [[NSFileManager alloc] init];\n    BOOL isDir;\n    if (![fm fileExistsAtPath:localPath isDirectory:&isDir]) {\n        \n        block(mkKxSMBError(KxSMBErrorFileIO,\n                           NSLocalizedString(@\"File '%@' is not exist\", nil),\n                           localPath.lastPathComponent));\n        return;\n    }\n    \n    if (isDir) {\n        \n        [self createFolderAtPath:smbPath\n                            auth:auth\n                           block:^(id result)\n         {\n             if ([result isKindOfClass:[KxSMBItemTree class]]) {\n                 \n                 [KxSMBProvider copyLocalFiles:[fm enumeratorAtPath:localPath]\n                                   localFolder:localPath\n                                     smbFolder:result\n                                     overwrite:overwrite\n                                      progress:progress\n                                         block:block];\n             } else {\n                 \n                 block([result isKindOfClass:[NSError class]] ? result : nil);\n             }\n         }];        \n        \n    } else {\n        \n        [KxSMBProvider copyLocalFile:localPath\n                             smbPath:smbPath\n                           overwrite:overwrite\n                                auth:auth\n                            progress:progress\n                               block:block];\n    }\n}\n\n- (void) copyFromPath:(NSString *)oldPath\n               toPath:(NSString *)newPath\n            overwrite:(BOOL)overwrite\n                 auth:(KxSMBAuth *)auth\n             progress:(KxSMBBlockProgress)progress\n                block:(KxSMBBlock)block\n{\n    [KxSMBProvider copyFileFromPath:oldPath\n                             toPath:newPath\n                          overwrite:overwrite\n                               auth:auth\n                           progress:progress\n                              block:block];\n}\n\n- (void) removeFolderAtPath:(NSString *)path\n                       auth:(KxSMBAuth *)auth\n                      block:(KxSMBBlock)block\n{\n    [self fetchAtPath:path\n            expandDir:YES\n                 auth:auth\n                block:^(id result)\n    {\n        if ([result isKindOfClass:[NSArray class]]) {\n            \n            NSMutableArray *folders = [NSMutableArray array];\n            NSMutableArray *items = [NSMutableArray array];\n            \n            for (KxSMBItem *item in result) {\n                \n                if ([item isKindOfClass:[KxSMBItemFile class]]) {\n                    \n                    [items addObject:item];\n                    \n                } else if ([item isKindOfClass:[KxSMBItemTree class]] &&\n                           (item.type == KxSMBItemTypeDir ||\n                            item.type == KxSMBItemTypeFileShare ||\n                            item.type == KxSMBItemTypeServer))\n                {\n                    [items addObject:item];\n                    [folders addObject:item];\n                }\n            }\n            \n            if (folders.count) {\n                \n                [KxSMBProvider enumerateSMBFolders:folders\n                                             items:items\n                                             block:^(id result)\n                 {\n                     if ([result isKindOfClass:[NSArray class]]) {\n                         \n                         NSMutableArray *reversed = [NSMutableArray array];\n                         for (id item in [result reverseObjectEnumerator]) {\n                             [reversed addObject:item];\n                         }\n                         \n                         [KxSMBProvider removeSMBItems:reversed block:^(id result) {\n                             \n                             if ([result isKindOfClass:[NSNumber class]]) {\n                             \n                                 [[KxSMBProvider sharedSmbProvider] removeAtPath:path\n                                                                            auth:auth\n                                                                           block:block];\n                                 \n                             } else {\n                                 \n                                 block([result isKindOfClass:[NSError class]] ? result : nil);\n                             }\n                         }];\n                         \n                     } else {\n                         \n                         block([result isKindOfClass:[NSError class]] ? result : nil);\n                     }\n                 }];\n                \n            } else if (items.count) {\n                \n                [KxSMBProvider removeSMBItems:items block:^(id result) {\n                    \n                    if ([result isKindOfClass:[NSNumber class]]) {\n                        \n                        [[KxSMBProvider sharedSmbProvider] removeAtPath:path\n                                                                   auth:auth\n                                                                  block:block];\n                        \n                    } else {\n                        \n                        block([result isKindOfClass:[NSError class]] ? result : nil);\n                    }\n                }];\n                \n            } else {\n                \n                [self removeAtPath:path auth:auth block:block];\n            }\n            \n        } else if ([result isKindOfClass:[KxSMBItemFile class]]) {\n            \n            block(mkKxSMBError(KxSMBErrorPathIsNotDir, path));\n            \n        } else {\n            \n            block([result isKindOfClass:[NSError class]] ? result : nil);\n        }        \n    }];\n}\n\n- (void) renameAtPath:(NSString *)oldPath\n              newPath:(NSString *)newPath\n                 auth:(KxSMBAuth *)auth\n                block:(KxSMBBlock)block\n{\n    NSParameterAssert(oldPath);\n    NSParameterAssert(newPath);    \n    NSParameterAssert(block);\n    \n    dispatch_async(_dispatchQueue, ^{\n        \n        id result = [KxSMBProvider renameAtPath:oldPath newPath:newPath auth:auth];\n        [KxSMBProvider fireBlock:block withResult:result];\n    });\n}\n\n#pragma mark - compatible (without auth)\n\n// without auth (compatible)\n\n- (void) fetchAtPath:(NSString *)path\n               block:(KxSMBBlock)block\n{\n    [self fetchAtPath:path expandDir:YES auth:nil block:block];\n}\n\n- (id) fetchAtPath:(NSString *)path\n{\n    return [self fetchAtPath:path expandDir:YES auth:nil];\n}\n\n- (void) createFileAtPath:(NSString *)path\n                overwrite:(BOOL)overwrite\n                    block:(KxSMBBlock)block\n{\n    [self createFileAtPath:path\n                 overwrite:overwrite\n                      auth:nil\n                     block:block];\n}\n\n- (id) createFileAtPath:(NSString *)path\n              overwrite:(BOOL)overwrite\n{\n    return [self createFileAtPath:path overwrite:overwrite auth:nil];\n}\n\n- (void) createFolderAtPath:(NSString *)path\n                      block:(KxSMBBlock)block\n{\n    [self createFolderAtPath:path\n                        auth:nil\n                       block:block];\n}\n\n- (id) createFolderAtPath:(NSString *)path\n{\n    return [self createFolderAtPath:path auth:nil];\n}\n\n- (void) removeAtPath:(NSString *)path\n                block:(KxSMBBlock)block\n{\n    [self removeAtPath:path\n                  auth:nil\n                 block:block];\n}\n\n- (id) removeAtPath:(NSString *)path\n{\n    return [self removeAtPath:path auth:nil];\n}\n\n- (void) copySMBPath:(NSString *)smbPath\n           localPath:(NSString *)localPath\n           overwrite:(BOOL)overwrite\n               block:(KxSMBBlock)block\n{\n    [self copySMBPath:smbPath\n            localPath:localPath\n            overwrite:overwrite\n                 auth:nil\n                block:block];\n}\n\n- (void) copyLocalPath:(NSString *)localPath\n               smbPath:(NSString *)smbPath\n             overwrite:(BOOL)overwrite\n                 block:(KxSMBBlock)block\n{\n    [self copyLocalPath:localPath\n                smbPath:smbPath\n              overwrite:overwrite\n                   auth:nil\n                  block:block];\n}\n\n- (void) copySMBPath:(NSString *)smbPath\n           localPath:(NSString *)localPath\n           overwrite:(BOOL)overwrite\n            progress:(KxSMBBlockProgress)progress\n               block:(KxSMBBlock)block\n{\n    [self copySMBPath:smbPath\n            localPath:localPath\n            overwrite:overwrite\n                 auth:nil\n             progress:progress\n                block:block];\n}\n\n- (void) copyLocalPath:(NSString *)localPath\n               smbPath:(NSString *)smbPath\n             overwrite:(BOOL)overwrite\n              progress:(KxSMBBlockProgress)progress\n                 block:(KxSMBBlock)block\n{\n    [self copyLocalPath:localPath\n                smbPath:smbPath\n              overwrite:overwrite\n                   auth:nil\n               progress:progress\n                  block:block];\n}\n\n- (void) removeFolderAtPath:(NSString *)path\n                      block:(KxSMBBlock)block\n{\n    [self removeFolderAtPath:path\n                        auth:nil\n                       block:block];\n}\n\n- (void) renameAtPath:(NSString *)oldPath\n              newPath:(NSString *)newPath\n                block:(KxSMBBlock)block\n{\n    [self renameAtPath:oldPath\n               newPath:newPath\n                  auth:nil\n                 block:block];\n\n}\n\n#if 0\n+ (void) dumpSmbcOptions:(SMBCCTX *)smbContext\n{\n    NSLog(@\"Debug: %d\", smbc_getDebug(smbContext));\n    NSLog(@\"NetbiosName: %s\", smbc_getNetbiosName(smbContext));\n    NSLog(@\"Workgroup: %s\", smbc_getWorkgroup(smbContext));\n    NSLog(@\"User: %s\", smbc_getUser(smbContext));\n    NSLog(@\"Timeout: %d\", smbc_getTimeout(smbContext));\n    NSLog(@\"DebugToStderr: %d\", smbc_getOptionDebugToStderr(smbContext));\n    NSLog(@\"FullTimeNames: %d\", smbc_getOptionFullTimeNames(smbContext));\n    NSLog(@\"OpenShareMode: %d\", smbc_getOptionOpenShareMode(smbContext));\n    NSLog(@\"EncryptionLevel: %d\", smbc_getOptionSmbEncryptionLevel(smbContext));\n    NSLog(@\"CaseSensitive: %d\", smbc_getOptionCaseSensitive(smbContext));\n    NSLog(@\"BrowseMaxLmbCount: %d\", smbc_getOptionBrowseMaxLmbCount(smbContext));\n    NSLog(@\"UrlEncodeReaddirEntries: %d\", smbc_getOptionUrlEncodeReaddirEntries(smbContext));\n    NSLog(@\"OneSharePerServer: %d\", smbc_getOptionOneSharePerServer(smbContext));\n    NSLog(@\"UseKerberos: %d\", smbc_getOptionUseKerberos(smbContext));\n    NSLog(@\"FallbackAfterKerberos: %d\", smbc_getOptionFallbackAfterKerberos(smbContext));\n    NSLog(@\"NoAutoAnonymousLogin: %d\", smbc_getOptionNoAutoAnonymousLogin(smbContext));\n    NSLog(@\"UseCCache: %d\", smbc_getOptionUseCCache(smbContext));\n    NSLog(@\"UseNTHash: %d\", smbc_getOptionUseNTHash(smbContext));\n}\n#endif\n\n\n@end\n\n///////////////////////////////////////////////////////////////////////////////\n\n@implementation KxSMBItemTree\n\n- (void) fetchItems:(KxSMBBlock) block\n{\n    NSParameterAssert(block);\n    \n    NSString *path = self.path;\n    KxSMBAuth *auth = self.auth;\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    [provider dispatchAsync: ^{\n        \n        id result = [KxSMBProvider fetchTreeAtPath:path auth:auth];\n        [KxSMBProvider fireBlock:block withResult:result];\n    }];\n}\n\n- (id) fetchItems\n{\n    __block id result = nil;\n    NSString *path = self.path;\n    KxSMBAuth *auth = self.auth;\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    [provider dispatchSync: ^{\n        result = [KxSMBProvider fetchTreeAtPath:path auth:auth];\n    }];\n    return result;\n}\n\n- (void) createFileWithName:(NSString *)name\n                  overwrite:(BOOL)overwrite\n                      block:(KxSMBBlock)block\n{\n    NSParameterAssert(name.length);\n    \n    if (self.type != KxSMBItemTypeDir ||\n        self.type != KxSMBItemTypeFileShare)\n    {\n        block(mkKxSMBError(KxSMBErrorPathIsNotDir, nil));\n        return;\n    }\n    \n    [[KxSMBProvider sharedSmbProvider] createFileAtPath:[self.path stringByAppendingSMBPathComponent:name]\n                                              overwrite:overwrite\n                                                   auth:self.auth\n                                                  block:block];\n\n}\n\n- (id) createFileWithName:(NSString *)name\n                overwrite:(BOOL)overwrite\n{\n    NSParameterAssert(name.length);\n    \n    if (self.type != KxSMBItemTypeDir ||\n        self.type != KxSMBItemTypeFileShare )\n    {\n        return mkKxSMBError(KxSMBErrorPathIsNotDir, nil);\n    }\n    \n    NSString *path = [self.path stringByAppendingSMBPathComponent:name];\n    return [[KxSMBProvider sharedSmbProvider] createFileAtPath:path\n                                                     overwrite:overwrite\n                                                          auth:self.auth];\n}\n\n- (void) removeWithName:(NSString *)name\n                  block:(KxSMBBlock)block\n{\n    if (self.type != KxSMBItemTypeDir ||\n        self.type != KxSMBItemTypeFileShare)\n    {\n        block(mkKxSMBError(KxSMBErrorPathIsNotDir, nil));\n        return;\n    }\n    \n    NSString *path = [self.path stringByAppendingSMBPathComponent:name];\n    [[KxSMBProvider sharedSmbProvider] removeAtPath:path\n                                               auth:self.auth\n                                              block:block];\n}\n\n- (id) removeWithName:(NSString *)name\n{\n    if (self.type != KxSMBItemTypeDir ||\n        self.type != KxSMBItemTypeFileShare )\n    {\n        return mkKxSMBError(KxSMBErrorPathIsNotDir, nil);\n    }\n    \n    NSString *path = [self.path stringByAppendingSMBPathComponent:name];\n    return [[KxSMBProvider sharedSmbProvider] removeAtPath:path\n                                                      auth:self.auth];\n}\n\n@end\n\n///////////////////////////////////////////////////////////////////////////////\n\n@interface KxSMBFileImpl : NSObject\n@end\n\n@implementation KxSMBFileImpl {\n    \n    SMBCCTX *_context;\n    SMBCFILE *_file;\n    NSString *_path;\n    KxSMBAuth *_auth;\n}\n\n- (id) initWithPath:(NSString *)path\n               auth:(KxSMBAuth *)auth\n{\n    self = [super init];\n    if (self) {\n        _path = path;\n        _auth = auth;\n    }\n    return self;\n}\n\n- (NSError *) openFile\n{\n    _context = [KxSMBProvider openSmbContext:_auth];\n    if (!_context) {\n        const int err = errno;\n        return mkKxSMBError(errnoToSMBErr(err),\n                            NSLocalizedString(@\"Unable init SMB context (errno:%d)\", nil), err);\n    }\n    \n    _file = smbc_getFunctionOpen(_context)(_context,\n                                           _path.UTF8String,\n                                           O_RDONLY,\n                                           0);\n    \n    if (!_file) {\n        [KxSMBProvider closeSmbContext:_context];\n        _context = NULL;\n        const int err = errno;\n        return mkKxSMBError(errnoToSMBErr(err),\n                            NSLocalizedString(@\"Unable open file:%@ (errno:%d)\", nil), _path, err);\n    }\n    \n    return nil;\n}\n\n- (NSError *) createFile:(BOOL)overwrite\n{\n    _context = [KxSMBProvider openSmbContext:_auth];\n    if (!_context) {\n        const int err = errno;\n        return mkKxSMBError(errnoToSMBErr(err),\n                            NSLocalizedString(@\"Unable init SMB context (errno:%d)\", nil), err);\n    }\n    \n    _file = smbc_getFunctionCreat(_context)(_context,\n                                           _path.UTF8String,\n                                            O_WRONLY|O_CREAT|(overwrite ? O_TRUNC : O_EXCL));\n    \n    if (!_file) {\n        [KxSMBProvider closeSmbContext:_context];\n        _context = NULL;\n        const int err = errno;\n        return mkKxSMBError(errnoToSMBErr(err),\n                            NSLocalizedString(@\"Unable open file:%@ (errno:%d)\", nil), _path, err);\n    }\n    \n    return nil;\n}\n\n- (void) closeFile\n{\n    if (_file) {\n        smbc_getFunctionClose(_context)(_context, _file);\n        _file = NULL;\n    }\n    if (_context) {\n        [KxSMBProvider closeSmbContext:_context];\n        _context = NULL;\n    }\n}\n\n- (id)readDataOfLength:(NSUInteger)length\n{\n    if (!_file) {\n        \n        NSError *error = [self openFile];\n        if (error) return error;        \n    }\n    \n    // it seems 512 kb is an optimal buffer size\n    const size_t bufferSize = MIN(length, 512*1024);\n    Byte *buffer = malloc(bufferSize);\n    if (!buffer) {\n        return mkKxSMBError(KxSMBErrorOutOfMemory, nil);\n    }\n    \n    smbc_read_fn readFn = smbc_getFunctionRead(_context);\n    NSMutableData *md = [NSMutableData data];\n    NSInteger bytesToRead = length;\n    \n    while (bytesToRead > 0) {\n        \n        ssize_t r = readFn(_context, _file, buffer, MIN(bytesToRead, bufferSize));\n        \n        if (r == 0)\n            break;\n        \n        if (r < 0) {\n                        \n            const int err = errno;\n            free(buffer);\n            return mkKxSMBError(errnoToSMBErr(err),\n                                NSLocalizedString(@\"Unable read file:%@ (errno:%d)\", nil), _path, err);\n        }\n        \n        [md appendBytes:buffer length:r];\n        bytesToRead -= r;\n    }\n    \n    free(buffer);\n    return md;\n}\n\n- (id)readDataToEndOfFile\n{\n    if (!_file) {\n        \n        NSError *error = [self openFile];\n        if (error) return error;\n    }\n    \n    Byte buffer[32768];\n    \n    smbc_read_fn readFn = smbc_getFunctionRead(_context);\n    \n    NSMutableData *md = [NSMutableData data];\n    \n    while (1) {\n        \n        ssize_t r = readFn(_context, _file, buffer, sizeof(buffer));\n        \n        if (r == 0)\n            break;\n        \n        if (r < 0) {\n            \n            const int err = errno;\n            return mkKxSMBError(errnoToSMBErr(err),\n                                NSLocalizedString(@\"Unable read file:%@ (errno:%d)\", nil), _path, err);\n        }\n        \n        [md appendBytes:buffer length:r];\n    }\n    \n    return md;\n}\n\n- (id)seekToFileOffset:(off_t)offset\n                whence:(NSInteger)whence\n{\n    if (!_file) {\n        \n        NSError *error = [self openFile];\n        if (error) return error;\n    }\n    \n    off_t r = smbc_getFunctionLseek(_context)(_context, _file, offset, (int)whence);\n    if (r < 0) {\n        const int err = errno;\n        return mkKxSMBError(errnoToSMBErr(err),\n                            NSLocalizedString(@\"Unable seek to file:%@ (errno:%d)\", nil), _path, errno);\n    }\n    return @(r);\n}\n\n- (id)writeData:(NSData *)data\n{\n    if (!_file) {\n        \n        NSError *error = [self createFile:NO];\n        if (error) return error;\n    }\n\n    smbc_write_fn writeFn = smbc_getFunctionWrite(_context);\n    NSInteger bytesToWrite = data.length;\n    const Byte *bytes = data.bytes;\n    \n    while (bytesToWrite > 0) {\n        \n        ssize_t r = writeFn(_context, _file, bytes, bytesToWrite);\n        if (r == 0)\n            break;\n        \n        if (r < 0) {\n            \n            const int err = errno;\n            return mkKxSMBError(errnoToSMBErr(err),\n                                NSLocalizedString(@\"Unable write file:%@ (errno:%d)\", nil), _path, err);\n        }\n\n        bytesToWrite -= r;\n        bytes += r;\n    }\n    \n    return @(data.length - bytesToWrite);\n}\n\n@end\n\n@implementation KxSMBItemFile {\n    \n    KxSMBFileImpl *_impl;\n}\n\n- (void) dealloc\n{\n    [self close];\n}\n\n- (void) close\n{\n    if (_impl) {\n        \n        KxSMBFileImpl *p = _impl;\n        _impl = nil;\n        \n        KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n        [provider dispatchAsync:^{ [p closeFile]; }];         \n    }\n}\n\n- (KxSMBFileImpl *)theImpl\n{\n    if (!_impl) {\n        _impl = [[KxSMBFileImpl alloc] initWithPath:self.path auth:self.auth];\n    }\n    return _impl;\n}\n\n- (void)readDataOfLength:(NSUInteger)length\n                   block:(KxSMBBlock)block\n{\n    NSParameterAssert(block);\n    \n    KxSMBFileImpl *p = self.theImpl;\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    [provider dispatchAsync:^{\n        \n        id result = [p readDataOfLength:length];\n        [KxSMBProvider fireBlock:block withResult:result];\n    }];\n}\n\n- (id)readDataOfLength:(NSUInteger)length\n{\n    __block id result = nil;\n    \n    KxSMBFileImpl *p = self.theImpl;\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    [provider dispatchSync:^{\n        result = [p readDataOfLength:length];\n    }];\n    return result;\n}\n\n- (void)readDataToEndOfFile:(KxSMBBlock)block\n{\n    NSParameterAssert(block);\n    \n    KxSMBFileImpl *p = self.theImpl;\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    [provider dispatchAsync:^{\n        \n        id result = [p readDataToEndOfFile];\n        [KxSMBProvider fireBlock:block withResult:result];\n    }];\n}\n\n- (id)readDataToEndOfFile\n{\n    __block id result = nil;\n    \n    KxSMBFileImpl *p = self.theImpl;\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    [provider dispatchSync:^{\n        result = [p readDataToEndOfFile];\n    }];\n    return result;\n}\n\n- (void)seekToFileOffset:(off_t)offset\n                  whence:(NSInteger)whence\n                   block:(KxSMBBlock) block\n{\n    NSParameterAssert(block);\n    \n    KxSMBFileImpl *p = self.theImpl;\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    [provider dispatchAsync:^{\n        \n        id result = [p seekToFileOffset:offset whence:whence];\n        [KxSMBProvider fireBlock:block withResult:result];\n    }];\n}\n\n- (id)seekToFileOffset:(off_t)offset\n                whence:(NSInteger)whence\n{\n    __block id result = nil;\n    \n    KxSMBFileImpl *p = self.theImpl;\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    [provider dispatchSync:^{\n        result = [p seekToFileOffset:offset whence:whence];\n    }];\n    return result;\n}\n\n- (void)writeData:(NSData *)data\n            block:(KxSMBBlock) block\n{\n    NSParameterAssert(block);\n    \n    KxSMBFileImpl *p = self.theImpl;\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    [provider dispatchAsync:^{\n        \n        id result = [p writeData:data];\n        [KxSMBProvider fireBlock:block withResult:result];\n    }];\n}\n\n- (id)writeData:(NSData *)data\n{\n    __block id result = nil;\n    \n    KxSMBFileImpl *p = self.theImpl;\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    [provider dispatchSync:^{\n        result = [p writeData:data];\n    }];\n    return result;\n\n}\n\n#pragma mark - internal\n\n- (id) createFile:(BOOL)overwrite\n{\n    return [self.theImpl createFile:overwrite];\n}\n\n@end\n\n///////////////////////////////////////////////////////////////////////////////\n\nstatic void my_smbc_get_auth_data_fn(const char *srv,\n                                     const char *shr,\n                                     char *workgroup, int wglen,\n                                     char *username, int unlen,\n                                     char *password, int pwlen)\n{\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    \n    KxSMBAuth *auth = nil;\n    __strong id<KxSMBProviderDelegate> delegate = provider.delegate;\n    if (delegate) {\n        \n        auth = [delegate smbRequestAuthServer:[NSString stringWithUTF8String:srv]\n                                        share:[NSString stringWithUTF8String:shr]\n                                    workgroup:[NSString stringWithUTF8String:workgroup]\n                                     username:[NSString stringWithUTF8String:username]];\n    }\n    \n    if (username) {\n        if (auth.username.length) {\n            strncpy(username, auth.username.UTF8String, unlen - 1);\n        } else {\n            strncpy(username, \"guest\", unlen - 1);\n        }\n    }\n    \n    if (password) {\n        if (auth.password.length) {\n            strncpy(password, auth.password.UTF8String, pwlen - 1);\n        } else {\n            password[0] = 0;\n        }\n    }\n    \n    if (workgroup) {\n        if (auth.workgroup.length) {\n            strncpy(workgroup, auth.workgroup.UTF8String, wglen - 1);\n        } else {\n            workgroup[0] = 0;\n        }\n    }\n    \n    // NSLog(@\"smb get auth for %s/%s -> %s/%s:%s\", srv, shr, workgroup, username, password);\n}\n\nstatic void my_smbc_get_auth_data_with_context_fn(SMBCCTX *c,\n                                                  const char *srv,\n                                                  const char *shr,\n                                                  char *workgroup, int wglen,\n                                                  char *username, int unlen,\n                                                  char *password, int pwlen)\n{\n    void *userdata = smbc_getOptionUserData(c);\n    if (userdata) {\n        \n        KxSMBAuth *auth = (__bridge KxSMBAuth *)userdata;\n        \n        if (username) {\n            if (auth.username.length) {\n                strncpy(username, auth.username.UTF8String, unlen - 1);\n            } else {\n                strncpy(username, \"guest\", unlen - 1);\n            }\n        }\n        \n        if (password) {\n            if (auth.password.length) {\n                strncpy(password, auth.password.UTF8String, pwlen - 1);\n            } else {\n                password[0] = 0;\n            }\n        }\n        \n        if (workgroup) {\n            if (auth.workgroup.length) {\n                strncpy(workgroup, auth.workgroup.UTF8String, wglen - 1);\n            } else {\n                workgroup[0] = 0;\n            }\n        }\n        \n    } else {\n        \n        my_smbc_get_auth_data_fn(srv, shr, workgroup, wglen, userdata, unlen, password, pwlen);\n    }\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\n@implementation NSString (KxSMB)\n\n// unfortunately, [NSString stringByAppendingPathComponent] brokes smb:// pathes\n// so need to use custom version\n\n- (NSString *) stringByAppendingSMBPathComponent: (NSString *) aString\n{\n    NSString *path = self;\n    if (![path hasSuffix:@\"/\"]) {\n        path = [path stringByAppendingString:@\"/\"];\n    }\n    return [path stringByAppendingString:aString];\n}\n\n@end\n"
  },
  {
    "path": "KxSMBSample/AppDelegate.h",
    "content": "//\n//  AppDelegate.h\n//  kxsmb project\n//  https://github.com/kolyvan/kxsmb/\n//\n//  Created by Kolyvan on 27.03.13.\n//\n\n/*\n Copyright (c) 2013 Konstantin Bukreev All rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are met:\n \n - Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n \n - Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#import <UIKit/UIKit.h>\n\n\n@interface AppDelegate : UIResponder <UIApplicationDelegate>\n\n@property (strong, nonatomic) UIWindow *window;\n\n@end\n"
  },
  {
    "path": "KxSMBSample/AppDelegate.m",
    "content": "//\n//  AppDelegate.m\n//  kxsmb project\n//  https://github.com/kolyvan/kxsmb/\n//\n//  Created by Kolyvan on 27.03.13.\n//\n\n/*\n Copyright (c) 2013 Konstantin Bukreev All rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are met:\n \n - Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n \n - Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\n#import \"AppDelegate.h\"\n#import \"TreeViewController.h\"\n#import \"SmbAuthViewController.h\"\n#import \"KxSMBProvider.h\"\n\n@interface AppDelegate() <KxSMBProviderDelegate, SmbAuthViewControllerDelegate>\n@end\n\n@implementation AppDelegate {\n\n    TreeViewController *_headVC;\n    NSMutableDictionary *_cachedAuths;\n    SmbAuthViewController *_smbAuthViewController;\n}\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions\n{   \n    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];\n    _headVC = [[TreeViewController alloc] initAsHeadViewController];\n    //_headVC.defaultAuth = [KxSMBAuth smbAuthWorkgroup:@\"\" username:@\"guest\" password:@\"\"];\n    \n    self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:_headVC];\n    [self.window makeKeyAndVisible];\n    \n    _cachedAuths = [NSMutableDictionary dictionary];\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    provider.delegate = self;\n    provider.config.browseMaxLmbCount = 0;\n    \n    return YES;\n}\n\n- (void)applicationWillResignActive:(UIApplication *)application\n{\n}\n\n- (void)applicationDidEnterBackground:(UIApplication *)application\n{\n}\n\n- (void)applicationWillEnterForeground:(UIApplication *)application\n{    \n}\n\n- (void)applicationDidBecomeActive:(UIApplication *)application\n{\n}\n\n- (void)applicationWillTerminate:(UIApplication *)application\n{\n}\n\n#pragma mark - KxSMBProviderDelegate\n\n- (void) presentSmbAuthViewControllerForServer:(NSString *)server\n                                         share:(NSString *)share\n                                     workgroup:(NSString *)workgroup\n                                      username:(NSString *)username\n{\n    if (!_smbAuthViewController) {\n        _smbAuthViewController = [[SmbAuthViewController alloc] init];\n        _smbAuthViewController.delegate = self;\n        _smbAuthViewController.username = @\"guest\";\n    }\n    \n    UINavigationController *nav = (UINavigationController *)self.window.rootViewController;\n    \n    if (nav.presentedViewController)\n        return;\n    \n    _smbAuthViewController.server = server;\n    _smbAuthViewController.workgroup = workgroup;\n    _smbAuthViewController.username = username;\n    \n    UIViewController *vc = [[UINavigationController alloc] initWithRootViewController:_smbAuthViewController];\n    \n    [nav.topViewController presentViewController:vc\n                                        animated:NO\n                                      completion:nil];\n}\n\n- (void) couldSmbAuthViewController:(SmbAuthViewController *) controller\n                               done:(BOOL) done\n{\n    if (done) {\n        \n        KxSMBAuth *auth = [KxSMBAuth smbAuthWorkgroup:controller.workgroup\n                                             username:controller.username\n                                             password:controller.password];\n        \n        _cachedAuths[controller.server.uppercaseString] = auth;\n        \n        NSLog(@\"store auth %@ -> (%@) %@:%@\", controller.server, controller.workgroup, controller.username, controller.password);\n    }\n    \n    UINavigationController *nav = (UINavigationController *)self.window.rootViewController;\n    [nav dismissViewControllerAnimated:YES completion:nil];\n    \n    [_headVC reloadPath];\n}\n\n- (KxSMBAuth *) smbRequestAuthServer:(NSString *)server\n                               share:(NSString *)share\n                           workgroup:(NSString *)workgroup\n                            username:(NSString *)username\n{\n    if ([share isEqualToString:@\"IPC$\"] ||\n        [share hasSuffix:@\"$\"])\n    {\n        // return nil;\n    }\n    \n    KxSMBAuth *auth = _cachedAuths[server.uppercaseString];\n    if (auth) {\n        \n        // NSLog(@\"cached auth for %@ -> %@ (%@) %@:%@\", server, share, auth.workgroup, auth.username, auth.password);\n        return auth;\n    }\n    \n    NSLog(@\"ask auth for %@/%@ (%@)\", server, share, workgroup);\n    \n    dispatch_async(dispatch_get_main_queue(), ^{\n    \n        [self presentSmbAuthViewControllerForServer:server\n                                              share:share\n                                          workgroup:workgroup\n                                           username:username];\n    });\n    \n    return nil;\n}\n\n@end\n"
  },
  {
    "path": "KxSMBSample/FileViewController.h",
    "content": "//\n//  FileViewController.h\n//  kxsmb project\n//  https://github.com/kolyvan/kxsmb/\n//\n//  Created by Kolyvan on 29.03.13.\n//\n\n/*\n Copyright (c) 2013 Konstantin Bukreev All rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are met:\n \n - Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n \n - Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#import <UIKit/UIKit.h>\n\n@class KxSMBItemFile;\n\n@interface FileViewController : UIViewController\n@property (readwrite, nonatomic, strong) KxSMBItemFile* smbFile;\n@end\n"
  },
  {
    "path": "KxSMBSample/FileViewController.m",
    "content": "//\n//  FileViewController.m\n//  kxsmb project\n//  https://github.com/kolyvan/kxsmb/\n//\n//  Created by Kolyvan on 29.03.13.\n//\n\n/*\n Copyright (c) 2013 Konstantin Bukreev All rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are met:\n \n - Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n \n - Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\n#import \"FileViewController.h\"\n#import \"KxSMBProvider.h\"\n#import <QuickLook/QuickLook.h>\n\n@interface FileViewController () <QLPreviewControllerDelegate, QLPreviewControllerDataSource>\n@end\n\n@implementation FileViewController {\n    \n    UIView          *_container;\n    UILabel         *_nameLabel;\n    UILabel         *_sizeLabel;\n    UILabel         *_modifiedLabel;\n    UILabel         *_createdLabel;\n    UIButton        *_downloadButton;\n    UIProgressView  *_downloadProgress;\n    UILabel         *_downloadLabel;\n    NSString        *_filePath;\n    NSFileHandle    *_fileHandle;\n    long            _downloadedBytes;\n    NSDate          *_timestamp;\n}\n\n- (id)init\n{\n    self = [super initWithNibName:nil bundle:nil];\n    if (self) {\n    }\n    return self;\n}\n\n- (void) dealloc\n{\n    [self closeFiles];\n}\n\n- (void)viewDidLoad\n{\n    [super viewDidLoad];\n    \n    const CGSize size = self.view.bounds.size;\n    const CGFloat W = size.width;\n    \n    _container = [[UIView alloc] initWithFrame:(CGRect){0,0,size}];\n    _container.autoresizingMask = UIViewAutoresizingNone;\n    _container.backgroundColor = [UIColor whiteColor];\n    [self.view addSubview:_container];\n    \n    _nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, W - 20, 25)];\n    _nameLabel.font = [UIFont boldSystemFontOfSize:16];\n    _nameLabel.textColor = [UIColor darkTextColor];\n    _nameLabel.opaque = NO;\n    _nameLabel.backgroundColor = [UIColor clearColor];\n    _nameLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;\n    \n    _sizeLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 35, W - 20, 25)];\n    _sizeLabel.font = [UIFont systemFontOfSize:14];\n    _sizeLabel.textColor = [UIColor darkTextColor];\n    _sizeLabel.opaque = NO;\n    _sizeLabel.backgroundColor = [UIColor clearColor];\n    _sizeLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;\n    \n    _modifiedLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 60, W - 20, 25)];\n    _modifiedLabel.font = [UIFont systemFontOfSize:14];;\n    _modifiedLabel.textColor = [UIColor darkTextColor];\n    _modifiedLabel.opaque = NO;\n    _modifiedLabel.backgroundColor = [UIColor clearColor];\n    _modifiedLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;\n    \n    _createdLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 85, W - 20, 25)];\n    _createdLabel.font = [UIFont systemFontOfSize:14];;\n    _createdLabel.textColor = [UIColor darkTextColor];\n    _createdLabel.opaque = NO;\n    _createdLabel.backgroundColor = [UIColor clearColor];\n    _createdLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;\n    \n    _downloadButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];\n    _downloadButton.frame = CGRectMake(10, 120, 100, 30);\n    _downloadButton.titleLabel.font = [UIFont boldSystemFontOfSize:16];\n    [_downloadButton setTitle:@\"Download\" forState:UIControlStateNormal];\n    [_downloadButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];\n    [_downloadButton addTarget:self action:@selector(downloadAction) forControlEvents:UIControlEventTouchUpInside];\n    \n    _downloadLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 150, W - 20, 40)];\n    _downloadLabel.font = [UIFont systemFontOfSize:14];;\n    _downloadLabel.textColor = [UIColor darkTextColor];\n    _downloadLabel.opaque = NO;\n    _downloadLabel.backgroundColor = [UIColor clearColor];\n    _downloadLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;\n    _downloadLabel.numberOfLines = 2;\n    \n    _downloadProgress = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];\n    _downloadProgress.frame = CGRectMake(10, 190, W - 20, 30);\n    _downloadProgress.hidden = YES;\n    \n    [_container addSubview:_nameLabel];\n    [_container addSubview:_sizeLabel];\n    [_container addSubview:_modifiedLabel];\n    [_container addSubview:_createdLabel];\n    [_container addSubview:_downloadButton];\n    [_container addSubview:_downloadLabel];\n    [_container addSubview:_downloadProgress];\n}\n\n- (void) viewDidLayoutSubviews\n{\n    [super viewDidLayoutSubviews];\n    \n    const CGSize size = self.view.bounds.size;\n    const CGFloat top = [self.topLayoutGuide length];\n    _container.frame = (CGRect){0, top, size.width, size.height - top};\n}\n\n- (void)viewWillAppear:(BOOL)animated\n{\n    [super viewWillAppear:animated];\n    \n    _nameLabel.text = _smbFile.path;\n    _sizeLabel.text = [NSString stringWithFormat:@\"size: %lld\", _smbFile.stat.size];\n    _modifiedLabel.text = [NSString stringWithFormat:@\"modified: %@\", _smbFile.stat.lastModified];\n    _createdLabel.text = [NSString stringWithFormat:@\"created: %@\", _smbFile.stat.creationTime];\n}\n\n- (void) viewWillDisappear:(BOOL)animated\n{\n    [super viewWillDisappear:animated];    \n    //[self closeFiles];\n}\n\n- (void) closeFiles\n{\n    if (_fileHandle) {\n        \n        [_fileHandle closeFile];\n        _fileHandle = nil;\n    }\n    \n    [_smbFile close];\n}\n\n- (void) downloadAction\n{\n    if (!_fileHandle) {\n        \n        NSString *folder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,\n                                                                NSUserDomainMask,\n                                                                YES) lastObject];\n        NSString *filename = _smbFile.path.lastPathComponent;\n        _filePath = [folder stringByAppendingPathComponent:filename];\n        \n        NSFileManager *fm = [[NSFileManager alloc] init];\n        if ([fm fileExistsAtPath:_filePath])\n            [fm removeItemAtPath:_filePath error:nil];\n        [fm createFileAtPath:_filePath contents:nil attributes:nil];\n        \n        NSError *error;\n        _fileHandle = [NSFileHandle fileHandleForWritingToURL:[NSURL fileURLWithPath:_filePath]\n                                                        error:&error];\n \n        if (_fileHandle) {\n        \n            [_downloadButton setTitle:@\"Cancel\" forState:UIControlStateNormal];\n            _downloadLabel.text = @\"starting ..\";\n            \n            _downloadedBytes = 0;\n            _downloadProgress.progress = 0;\n            _downloadProgress.hidden = NO;\n            _timestamp = [NSDate date];\n            \n            [self download];\n            \n        } else {\n            \n            _downloadLabel.text = [NSString stringWithFormat:@\"failed: %@\", error.localizedDescription];\n        }\n        \n    } else {\n        \n        [_downloadButton setTitle:@\"Download\" forState:UIControlStateNormal];\n        _downloadLabel.text = @\"cancelled\";\n        [self closeFiles];\n    }\n}\n\n-(void) updateDownloadStatus: (id) result\n{\n    if ([result isKindOfClass:[NSError class]]) {\n         \n        NSError *error = result;\n        \n        [_downloadButton setTitle:@\"Download\" forState:UIControlStateNormal];\n        _downloadLabel.text = [NSString stringWithFormat:@\"failed: %@\", error.localizedDescription];\n        _downloadProgress.hidden = YES;        \n       [self closeFiles];\n        \n    } else if ([result isKindOfClass:[NSData class]]) {\n        \n        NSData *data = result;\n                \n        if (data.length == 0) {\n        \n            [_downloadButton setTitle:@\"Download\" forState:UIControlStateNormal];          \n            [self closeFiles];\n            \n        } else {\n            \n            NSTimeInterval time = -[_timestamp timeIntervalSinceNow];\n            \n            _downloadedBytes += data.length;\n            _downloadProgress.progress = (float)_downloadedBytes / (float)_smbFile.stat.size;\n            \n            CGFloat value;\n            NSString *unit;\n            \n            if (_downloadedBytes < 1024) {\n                \n                value = _downloadedBytes;\n                unit = @\"B\";\n                \n            } else if (_downloadedBytes < 1048576) {\n                \n                value = _downloadedBytes / 1024.f;\n                unit = @\"KB\";\n                \n            } else {\n                \n                value = _downloadedBytes / 1048576.f;\n                unit = @\"MB\";\n            }\n            \n            _downloadLabel.text = [NSString stringWithFormat:@\"downloaded %.1f%@ (%.1f%%) %.2f%@s\",\n                                   value, unit,\n                                   _downloadProgress.progress * 100.f,\n                                   value / time, unit];\n            \n            if (_fileHandle) {\n                \n                [_fileHandle writeData:data];\n                \n                if(_downloadedBytes == _smbFile.stat.size) {\n                    \n                    [self closeFiles];\n                    \n                    [_downloadButton setTitle:@\"Done\" forState:UIControlStateNormal];\n                    _downloadButton.enabled = NO;\n                    \n                    if ([QLPreviewController canPreviewItem:[NSURL fileURLWithPath:_filePath]]) {\n                        \n                        QLPreviewController *vc = [QLPreviewController new];\n                        vc.delegate = self;\n                        vc.dataSource = self;\n                        [self.navigationController pushViewController:vc animated:YES];\n                    }\n                    \n                } else {\n                    \n                    [self download];\n                }\n            }\n        }\n    } else {\n        \n        NSAssert(false, @\"bugcheck\");        \n    }\n}\n\n- (void) download\n{    \n    __weak __typeof(self) weakSelf = self;\n    [_smbFile readDataOfLength:1024*1024\n                         block:^(id result)\n    {\n        FileViewController *p = weakSelf;\n        //if (p && p.isViewLoaded && p.view.window) {\n        if (p) {\n            [p updateDownloadStatus:result];\n        }\n    }];\n}\n\n#pragma mark - QLPreviewController\n\n- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller\n{\n    return 1;\n}\n\n- (id <QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index\n{\n    return [NSURL fileURLWithPath:_filePath];\n}\n\n@end\n"
  },
  {
    "path": "KxSMBSample/KxSMBSample-Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleDisplayName</key>\n\t<string>${PRODUCT_NAME}</string>\n\t<key>CFBundleExecutable</key>\n\t<string>${EXECUTABLE_NAME}</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>ru.kolyvan.${PRODUCT_NAME:rfc1034identifier}</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>${PRODUCT_NAME}</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UIFileSharingEnabled</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "KxSMBSample/KxSMBSample-Prefix.pch",
    "content": "//\n// Prefix header for all source files of the 'KxSMBSample' target in the 'KxSMBSample' project\n//\n\n#import <Availability.h>\n\n#ifndef __IPHONE_4_0\n#warning \"This project uses features only available in iOS SDK 4.0 and later.\"\n#endif\n\n#ifdef __OBJC__\n    #import <UIKit/UIKit.h>\n    #import <Foundation/Foundation.h>\n#endif\n"
  },
  {
    "path": "KxSMBSample/SmbAuthViewController.h",
    "content": "//\n//  SmbAuthViewController.h\n//  kxsmb project\n//  https://github.com/kolyvan/kxsmb/\n//\n//  Created by Kolyvan on 29.03.13.\n//\n\n/*\n Copyright (c) 2013 Konstantin Bukreev All rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are met:\n \n - Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n \n - Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#import <UIKit/UIKit.h>\n\n@class SmbAuthViewController;\n\n@protocol SmbAuthViewControllerDelegate\n@optional\n- (void) couldSmbAuthViewController: (SmbAuthViewController *) controller\n                               done: (BOOL) done;\n@end\n\n@interface SmbAuthViewController : UIViewController\n@property (readwrite, nonatomic, weak) id delegate;\n@property (readwrite, nonatomic, strong) NSString *server;\n@property (readwrite, nonatomic, strong) NSString *workgroup;\n@property (readwrite, nonatomic, strong) NSString *username;\n@property (readwrite, nonatomic, strong) NSString *password;\n@end\n"
  },
  {
    "path": "KxSMBSample/SmbAuthViewController.m",
    "content": "//\n//  SmbAuthViewController.m\n//  kxsmb project\n//  https://github.com/kolyvan/kxsmb/\n//\n//  Created by Kolyvan on 29.03.13.\n//\n\n/*\n Copyright (c) 2013 Konstantin Bukreev All rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are met:\n \n - Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n \n - Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\n#import \"SmbAuthViewController.h\"\n\n@interface SmbAuthViewController ()\n@end\n\n@implementation SmbAuthViewController {\n\n    UIView      *_container;\n    UILabel     *_pathLabel;\n    UITextField *_workgroupField;\n    UITextField *_usernameField;\n    UITextField *_passwordField;\n}\n\n- (id)init\n{\n    self = [super initWithNibName:nil bundle:nil];\n    if (self) {\n        self.title =  NSLocalizedString(@\"SMB Authorization\", nil);\n    }\n    return self;\n}\n\n- (void)viewDidLoad\n{\n    [super viewDidLoad];\n    \n    const CGSize size = self.view.bounds.size;\n    const CGFloat W = size.width;\n    //const CGFloat H = size.height;\n    \n    _container = [[UIView alloc] initWithFrame:(CGRect){0,0,size}];\n    _container.autoresizingMask = UIViewAutoresizingNone;\n    _container.backgroundColor = [UIColor whiteColor];\n    [self.view addSubview:_container];\n    \n    _pathLabel = [[UILabel alloc] initWithFrame:CGRectMake(10,10,W-20,30)];\n    _pathLabel.backgroundColor = [UIColor clearColor];\n    _pathLabel.textColor = [UIColor darkTextColor];\n    _pathLabel.font = [UIFont systemFontOfSize:16];\n    [_container addSubview:_pathLabel];\n    \n    UILabel *workgroupLabel;\n    workgroupLabel = [[UILabel alloc] initWithFrame:CGRectMake(10,40,90,30)];\n    workgroupLabel.backgroundColor = [UIColor clearColor];\n    workgroupLabel.textColor = [UIColor darkTextColor];\n    workgroupLabel.font = [UIFont boldSystemFontOfSize:16];\n    workgroupLabel.text = NSLocalizedString(@\"Workgroup\", nil);\n    [_container addSubview:workgroupLabel];\n    \n    UILabel *usernameLabel;\n    usernameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10,90,90,30)];\n    usernameLabel.backgroundColor = [UIColor clearColor];\n    usernameLabel.textColor = [UIColor darkTextColor];\n    usernameLabel.font = [UIFont boldSystemFontOfSize:16];\n    usernameLabel.text = NSLocalizedString(@\"Username\", nil);\n    [_container addSubview:usernameLabel];\n    \n    UILabel *passwordLabel;\n    passwordLabel = [[UILabel alloc] initWithFrame:CGRectMake(10,140,90,30)];\n    passwordLabel.backgroundColor = [UIColor clearColor];\n    passwordLabel.textColor =  [UIColor darkTextColor];\n    passwordLabel.font = [UIFont boldSystemFontOfSize:16];\n    passwordLabel.text = NSLocalizedString(@\"Password\", nil);\n    [_container addSubview:passwordLabel];\n    \n    _workgroupField = [[UITextField alloc] initWithFrame:CGRectMake(100, 41, W - 110, 30)];\n    _workgroupField.autocapitalizationType = UITextAutocapitalizationTypeNone;\n    _workgroupField.autocorrectionType = UITextAutocorrectionTypeNo;\n    _workgroupField.spellCheckingType = UITextSpellCheckingTypeNo;\n    _workgroupField.autoresizingMask = UIViewAutoresizingFlexibleWidth;\n    _workgroupField.clearButtonMode =  UITextFieldViewModeWhileEditing;\n    _workgroupField.textColor = [UIColor blueColor];\n    _workgroupField.font = [UIFont systemFontOfSize:16];\n    _workgroupField.borderStyle = UITextBorderStyleRoundedRect;\n    _workgroupField.backgroundColor = [UIColor lightGrayColor];\n    _workgroupField.returnKeyType = UIReturnKeyNext;\n    \n    [_workgroupField addTarget:self\n                        action:@selector(textFieldDoneEditing:)\n              forControlEvents:UIControlEventEditingDidEndOnExit];\n    \n    [_container addSubview:_workgroupField];\n    \n    _usernameField = [[UITextField alloc] initWithFrame:CGRectMake(100, 91, W - 110, 30)];\n    _usernameField.autocapitalizationType = UITextAutocapitalizationTypeNone;\n    _usernameField.autocorrectionType = UITextAutocorrectionTypeNo;\n    _usernameField.spellCheckingType = UITextSpellCheckingTypeNo;\n    _usernameField.autoresizingMask = UIViewAutoresizingFlexibleWidth;\n    _usernameField.clearButtonMode =  UITextFieldViewModeWhileEditing;\n    _usernameField.textColor = [UIColor blueColor];\n    _usernameField.font = [UIFont systemFontOfSize:16];\n    _usernameField.borderStyle = UITextBorderStyleRoundedRect;\n    _usernameField.backgroundColor = [UIColor lightGrayColor];\n    _usernameField.returnKeyType = UIReturnKeyDone;\n    \n    [_usernameField addTarget:self\n                       action:@selector(textFieldDoneEditing:)\n             forControlEvents:UIControlEventEditingDidEndOnExit];\n    \n    [_container addSubview:_usernameField];\n    \n    _passwordField = [[UITextField alloc] initWithFrame:CGRectMake(100, 141, W - 110, 30)];\n    _passwordField.autocapitalizationType = UITextAutocapitalizationTypeNone;\n    _passwordField.autocorrectionType = UITextAutocorrectionTypeNo;\n    _passwordField.spellCheckingType = UITextSpellCheckingTypeNo;\n    _passwordField.autoresizingMask = UIViewAutoresizingFlexibleWidth;\n    _passwordField.clearButtonMode =  UITextFieldViewModeWhileEditing;\n    _passwordField.textColor = [UIColor blueColor];\n    _passwordField.font = [UIFont systemFontOfSize:16];\n    _passwordField.borderStyle = UITextBorderStyleRoundedRect;\n    _passwordField.backgroundColor = [UIColor lightGrayColor];\n    _passwordField.returnKeyType = UIReturnKeyDone;\n    _passwordField.secureTextEntry = YES;\n    \n    [_passwordField addTarget:self\n                       action:@selector(textFieldDoneEditing:)\n             forControlEvents:UIControlEventEditingDidEndOnExit];\n    \n    [_container addSubview:_passwordField];\n\n    \n    UIBarButtonItem *bbi;\n    \n    bbi = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone\n                                                        target:self\n                                                        action:@selector(doneAction)];\n    \n    self.navigationItem.rightBarButtonItem = bbi;\n    \n    bbi = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel\n                                                        target:self\n                                                        action:@selector(cancelAction)];\n    \n    self.navigationItem.leftBarButtonItem = bbi;\n}\n\n- (void) viewDidLayoutSubviews\n{\n    [super viewDidLayoutSubviews];\n    \n    const CGSize size = self.view.bounds.size;\n    const CGFloat top = [self.topLayoutGuide length];\n    _container.frame = (CGRect){0, top, size.width, size.height - top};\n}\n\n- (void) viewWillAppear:(BOOL)animated\n{\n    [super viewWillAppear:animated];\n    \n    _pathLabel.text = [NSString stringWithFormat:NSLocalizedString(@\"Server: %@\", nil), _server];\n    _workgroupField.text = _workgroup;\n    _usernameField.text = _username;\n    _passwordField.text = _password;\n    \n    [_workgroupField becomeFirstResponder];\n}\n\n- (void) textFieldDoneEditing: (id) sender\n{\n}\n\n- (void) cancelAction\n{\n    __strong id p = self.delegate;\n    if (p && [p respondsToSelector:@selector(couldSmbAuthViewController:done:)])\n        [p couldSmbAuthViewController:self done:NO];\n}\n\n- (void) doneAction\n{\n    _workgroup = _workgroupField.text;\n    _username = _usernameField.text;\n    _password = _passwordField.text;\n    \n    __strong id p = self.delegate;\n    if (p && [p respondsToSelector:@selector(couldSmbAuthViewController:done:)])\n        [p couldSmbAuthViewController:self done:YES];\n}\n\n@end\n"
  },
  {
    "path": "KxSMBSample/TreeViewController.h",
    "content": "//\n//  TreeViewController.h\n//  kxsmb project\n//  https://github.com/kolyvan/kxsmb/\n//\n//  Created by Kolyvan on 27.03.13.\n//\n\n/*\n Copyright (c) 2013 Konstantin Bukreev All rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are met:\n \n - Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n \n - Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n\n#import <UIKit/UIKit.h>\n\n@class KxSMBAuth;\n\n@interface TreeViewController : UITableViewController <UIAlertViewDelegate>\n- (id)initAsHeadViewController;\n- (void) reloadPath;\n@property (readwrite, nonatomic, strong) NSString *path;\n@property (readwrite, nonatomic, strong) KxSMBAuth *defaultAuth;\n@end\n"
  },
  {
    "path": "KxSMBSample/TreeViewController.m",
    "content": "//\n//  TreeViewController.m\n//  kxsmb project\n//  https://github.com/kolyvan/kxsmb/\n//\n//  Created by Kolyvan on 27.03.13.\n//\n\n/*\n Copyright (c) 2013 Konstantin Bukreev All rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are met:\n \n - Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n \n - Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#import \"TreeViewController.h\"\n#import \"FileViewController.h\"\n#import \"KxSMBProvider.h\"\n\n@interface TreeViewController () <UITableViewDataSource, UITableViewDelegate>\n@end\n\n@implementation TreeViewController {\n    \n    BOOL        _isHeadVC;\n    NSArray     *_items;\n    BOOL        _loading;\n    BOOL        _needNewPath;\n    UITextField *_newPathField;\n}\n\n- (void) setPath:(NSString *)path\n{\n    _path = path;\n    [self reloadPath];\n}\n\n- (id)init\n{\n    self = [super init];\n    if (self) {\n        \n        self.title = @\"\";\n        _needNewPath = YES;\n        _isHeadVC = NO;\n    }\n    return self;\n}\n\n- (id)initAsHeadViewController {\n    if((self = [self init])) {\n        _isHeadVC = YES;\n    }\n    return self;\n}\n\n- (void)viewDidLoad\n{\n    [super viewDidLoad];\n    \n    if(NSClassFromString(@\"UIRefreshControl\")) {\n        UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];\n        [refreshControl addTarget:self action:@selector(reloadPath) forControlEvents:UIControlEventValueChanged];\n        self.refreshControl = refreshControl;\n    }\n    \n    if(_isHeadVC) {\n        self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch\n                                                                                              target:self\n                                                                                              action:@selector(requestNewPath)];\n    }\n    \n    self.navigationItem.rightBarButtonItems =\n    @[\n      [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd\n                                                    target:self\n                                                    action:@selector(actionMkDir:)],\n      \n      [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave\n                                                    target:self\n                                                    action:@selector(actionCopyFile:)],\n      ];\n}\n\n- (void)didReceiveMemoryWarning\n{\n    [super didReceiveMemoryWarning];\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation\n{\n    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);\n}\n\n- (void)viewWillAppear:(BOOL)animated\n{\n    [super viewWillAppear:animated];\n\n}\n\n- (void)viewDidAppear:(BOOL)animated {\n    \n    [super viewDidAppear:animated];\n    \n    if (self.navigationController.childViewControllers.count == 1 && _needNewPath) {\n        _needNewPath = NO;\n        [self requestNewPath];\n    }\n}\n\n- (void) reloadPath\n{\n    NSString *path;\n    \n    if (_path.length) {\n        \n        path = _path;\n        self.title = path.lastPathComponent;\n        \n    } else {\n        \n        path = @\"smb://\";\n        self.title = @\"smb://\";\n    }\n    \n    _items = nil;\n    [self.tableView reloadData];\n    [self updateStatus:[NSString stringWithFormat: @\"Fetching %@..\", path]];\n    \n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    [provider fetchAtPath:path\n                     auth:_defaultAuth\n                    block:^(id result)\n    {\n        if ([result isKindOfClass:[NSError class]]) {\n            \n            [self updateStatus:result];\n            \n        } else {\n        \n            [self updateStatus:nil];\n            \n            if ([result isKindOfClass:[NSArray class]]) {\n                \n                _items = [result copy];\n                \n            } else if ([result isKindOfClass:[KxSMBItem class]]) {\n                \n                _items = @[result];\n            }\n            \n            [self.tableView reloadData];\n        }\n    }];\n}\n\n- (void) requestNewPath\n{\n    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@\"Connect to Host\"\n                                                                   message:nil\n                                                            preferredStyle:UIAlertControllerStyleAlert];\n    \n    [alert addTextFieldWithConfigurationHandler:^(UITextField * textField) {\n        textField.text = [[NSUserDefaults standardUserDefaults] objectForKey:@\"LastServer\"] ?: @\"smb://\";\n        textField.placeholder = @\"smb://\";\n        textField.clearButtonMode = UITextFieldViewModeAlways;\n    }];\n    \n    [alert addAction:[UIAlertAction actionWithTitle:@\"Go\"\n                                              style:UIAlertActionStyleDefault\n                                            handler:^(UIAlertAction *action)\n    {\n        self.path = alert.textFields[0].text;\n        [[NSUserDefaults standardUserDefaults] setObject:_newPathField.text forKey:@\"LastServer\"];\n    }]];\n     \n    [alert addAction:[UIAlertAction actionWithTitle:@\"Cancel\"\n                                              style:UIAlertActionStyleCancel\n                                            handler:nil]];\n    \n\n    [self presentViewController:alert animated:YES completion:nil];\n}\n\n- (void) updateStatus: (id) status\n{\n    UIFont *font = [UIFont boldSystemFontOfSize:16];\n    \n    if ([status isKindOfClass:[NSString class]]) {\n    \n        UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];\n        \n        CGSize sz = activityIndicator.frame.size;        \n        const float H = font.lineHeight + sz.height + 10;\n        const float W = self.tableView.frame.size.width;\n        \n        UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, W, H)];\n        \n        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 5, W, font.lineHeight)];\n        label.text = status;\n        label.font = font;\n        label.textColor = [UIColor grayColor];\n        label.textAlignment = NSTextAlignmentCenter;\n        label.opaque = NO;\n        label.backgroundColor = [UIColor clearColor];\n        label.autoresizingMask = UIViewAutoresizingFlexibleWidth;\n        \n        [v addSubview:label];\n        \n        if(![self.refreshControl isRefreshing])\n            [self.refreshControl beginRefreshing];\n        \n        self.tableView.tableHeaderView = v;\n        \n    } else if ([status isKindOfClass:[NSError class]]) {\n        \n        const float W = self.tableView.frame.size.width;\n        \n        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 5, W, font.lineHeight)];\n        label.text = ((NSError *)status).localizedDescription;\n        label.font = font;\n        label.textColor = [UIColor redColor];\n        label.textAlignment = NSTextAlignmentCenter;\n        label.opaque = NO;\n        label.backgroundColor = [UIColor clearColor];\n        label.autoresizingMask = UIViewAutoresizingFlexibleWidth;\n        \n        self.tableView.tableHeaderView = label;\n        \n        [self.refreshControl endRefreshing];\n        \n    } else {\n        \n        self.tableView.tableHeaderView = nil;\n        \n        [self.refreshControl endRefreshing];\n    }\n}\n\n- (void) actionCopyFile:(id)sender\n{\n    NSString *name = [NSString stringWithFormat:@\"%u.tmp\", (unsigned)[NSDate timeIntervalSinceReferenceDate]];\n    NSString *path = [_path stringByAppendingSMBPathComponent:name];\n    \n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    [provider createFileAtPath:path overwrite:YES auth:_defaultAuth block:^(id result) {\n        \n        if ([result isKindOfClass:[KxSMBItemFile class]]) {\n            \n            NSData *data = [@\"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\" dataUsingEncoding:NSUTF8StringEncoding];\n            \n            KxSMBItemFile *itemFile = result;\n            [itemFile writeData:data block:^(id result) {\n                \n                NSLog(@\"completed:%@\", result);\n                if (![result isKindOfClass:[NSError class]]) {\n                    [self reloadPath];\n                }\n            }];\n            \n        } else {\n            \n            NSLog(@\"%@\", result);\n        }\n    }];     \n}\n\n- (void) actionMkDir:(id)sender\n{\n    NSString *path = [_path stringByAppendingSMBPathComponent:@\"NewFolder\"];\n    KxSMBProvider *provider = [KxSMBProvider sharedSmbProvider];\n    id result = [provider createFolderAtPath:path auth:_defaultAuth];\n    if ([result isKindOfClass:[KxSMBItemTree class]]) {\n        \n        NSMutableArray *ma = [_items mutableCopy];\n        [ma addObject:result];\n        _items = [ma copy];\n        \n        [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:_items.count-1 inSection:0]]\n                              withRowAnimation:UITableViewRowAnimationAutomatic];\n        \n    } else {\n        \n        NSLog(@\"%@\", result);\n    }\n}\n\n#pragma mark - Table view data source\n\n- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView\n{\n    return 1;\n}\n\n- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section\n{\n    return _items.count;\n}\n\n- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath\n{\n    static NSString *cellIdentifier = @\"Cell\";\n    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];\n    if (cell == nil) {\n        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1\n                                      reuseIdentifier:cellIdentifier];\n    }\n    \n    KxSMBItem *item = _items[indexPath.row];\n    cell.textLabel.text = item.path.lastPathComponent;\n    \n    if ([item isKindOfClass:[KxSMBItemTree class]]) {\n        \n        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;\n        cell.detailTextLabel.text =  @\"\";\n        \n    } else {\n        \n        cell.accessoryType = UITableViewCellAccessoryNone;\n        cell.detailTextLabel.text = [NSString stringWithFormat:@\"%lld\", item.stat.size];\n    }\n    \n    return cell;\n}\n\n#pragma mark - Table view delegate\n\n- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath\n{\n    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];\n    \n    KxSMBItem *item = _items[indexPath.row];\n    if ([item isKindOfClass:[KxSMBItemTree class]]) {\n        \n        TreeViewController *vc = [[TreeViewController alloc] init];\n        vc.defaultAuth = _defaultAuth;\n        vc.path = item.path;\n        [self.navigationController pushViewController:vc animated:YES];\n        \n    } else if ([item isKindOfClass:[KxSMBItemFile class]]) {\n        \n        FileViewController *vc = [[FileViewController alloc] init];\n        vc.smbFile = (KxSMBItemFile *)item;\n        [self.navigationController pushViewController:vc animated:YES];\n    }\n}\n\n- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath\n{\n    return UITableViewCellEditingStyleDelete;\n}\n\n- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath\n{\n    if (editingStyle == UITableViewCellEditingStyleDelete) {\n        \n        KxSMBItem *item = _items[indexPath.row];\n        [[KxSMBProvider sharedSmbProvider] removeAtPath:item.path auth:_defaultAuth block:^(id result) {\n            \n            NSLog(@\"completed:%@\", result);\n            if (![result isKindOfClass:[NSError class]]) {\n                [self reloadPath];\n            }\n        }];        \n    }\n}\n\n#pragma mark - Alert view delegate\n\n- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {\n    if(buttonIndex == 1) {\n        self.path = _newPathField.text;\n        [[NSUserDefaults standardUserDefaults] setObject:_newPathField.text forKey:@\"LastServer\"];\n        [[NSUserDefaults standardUserDefaults] synchronize];\n    }\n}\n\n@end\n"
  },
  {
    "path": "KxSMBSample/en.lproj/InfoPlist.strings",
    "content": "/* Localized versions of Info.plist keys */\n\n"
  },
  {
    "path": "KxSMBSample/main.m",
    "content": "//\n//  main.m\n//  KxSMBSample\n//\n//  Created by Kolyvan on 30.03.13.\n//  Copyright (c) 2013 Konstantin Bukreev. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n#import \"AppDelegate.h\"\n\nint main(int argc, char *argv[])\n{\n    @autoreleasepool {\n        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));\n    }\n}\n"
  },
  {
    "path": "KxSMBSample.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t87085F8D1705D46C009CD258 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 87085F8C1705D46C009CD258 /* UIKit.framework */; };\n\t\t87085F8F1705D46C009CD258 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 87085F8E1705D46C009CD258 /* Foundation.framework */; };\n\t\t87085F911705D46C009CD258 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 87085F901705D46C009CD258 /* CoreGraphics.framework */; };\n\t\t87085F971705D46C009CD258 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 87085F951705D46C009CD258 /* InfoPlist.strings */; };\n\t\t87085F991705D46C009CD258 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 87085F981705D46C009CD258 /* main.m */; };\n\t\t87085F9D1705D46C009CD258 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 87085F9C1705D46C009CD258 /* AppDelegate.m */; };\n\t\t87085F9F1705D46C009CD258 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 87085F9E1705D46C009CD258 /* Default.png */; };\n\t\t87085FA11705D46C009CD258 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 87085FA01705D46C009CD258 /* Default@2x.png */; };\n\t\t87085FA31705D46C009CD258 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 87085FA21705D46C009CD258 /* Default-568h@2x.png */; };\n\t\t87085FB41705D494009CD258 /* KxSMBProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 87085FB31705D494009CD258 /* KxSMBProvider.m */; };\n\t\t87085FBB1705D4AB009CD258 /* FileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 87085FB61705D4AB009CD258 /* FileViewController.m */; };\n\t\t87085FBC1705D4AB009CD258 /* SmbAuthViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 87085FB81705D4AB009CD258 /* SmbAuthViewController.m */; };\n\t\t87085FBD1705D4AB009CD258 /* TreeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 87085FBA1705D4AB009CD258 /* TreeViewController.m */; };\n\t\t87085FC41705D4CA009CD258 /* libsmbclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 87085FBF1705D4CA009CD258 /* libsmbclient.a */; };\n\t\t87085FC51705D4CA009CD258 /* libtalloc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 87085FC11705D4CA009CD258 /* libtalloc.a */; };\n\t\t87085FC61705D4CA009CD258 /* libtdb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 87085FC21705D4CA009CD258 /* libtdb.a */; };\n\t\t87085FC71705D4CA009CD258 /* libwbclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 87085FC31705D4CA009CD258 /* libwbclient.a */; };\n\t\t87085FC91705D4FD009CD258 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 87085FC81705D4FD009CD258 /* libz.dylib */; };\n\t\t87085FCB1705D503009CD258 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 87085FCA1705D503009CD258 /* libiconv.dylib */; };\n\t\t87085FCD1705D509009CD258 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 87085FCC1705D509009CD258 /* libresolv.dylib */; };\n\t\t871CC5751774589C00EDD76D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 87085F8E1705D46C009CD258 /* Foundation.framework */; };\n\t\t871CC580177458AD00EDD76D /* KxSMBProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 87085FB31705D494009CD258 /* KxSMBProvider.m */; };\n\t\tEAC6EFEE179A4133005AC807 /* libtevent.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EAC6EFED179A4133005AC807 /* libtevent.a */; };\n\t\tF992AF0C1BC3D3CC0063A4B3 /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F992AF0B1BC3D3CC0063A4B3 /* QuickLook.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t871CC5721774589C00EDD76D /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"include/${PRODUCT_NAME}\";\n\t\t\tdstSubfolderSpec = 16;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t87085F891705D46C009CD258 /* KxSMBSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KxSMBSample.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t87085F8C1705D46C009CD258 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };\n\t\t87085F8E1705D46C009CD258 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };\n\t\t87085F901705D46C009CD258 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };\n\t\t87085F941705D46C009CD258 /* KxSMBSample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = \"KxSMBSample-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t87085F961705D46C009CD258 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = \"<group>\"; };\n\t\t87085F981705D46C009CD258 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = \"<group>\"; };\n\t\t87085F9A1705D46C009CD258 /* KxSMBSample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"KxSMBSample-Prefix.pch\"; sourceTree = \"<group>\"; };\n\t\t87085F9B1705D46C009CD258 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = \"<group>\"; };\n\t\t87085F9C1705D46C009CD258 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AppDelegate.m; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };\n\t\t87085F9E1705D46C009CD258 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = \"<group>\"; };\n\t\t87085FA01705D46C009CD258 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Default@2x.png\"; sourceTree = \"<group>\"; };\n\t\t87085FA21705D46C009CD258 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Default-568h@2x.png\"; sourceTree = \"<group>\"; };\n\t\t87085FB21705D494009CD258 /* KxSMBProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KxSMBProvider.h; sourceTree = \"<group>\"; };\n\t\t87085FB31705D494009CD258 /* KxSMBProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KxSMBProvider.m; sourceTree = \"<group>\"; };\n\t\t87085FB51705D4AB009CD258 /* FileViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = FileViewController.h; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };\n\t\t87085FB61705D4AB009CD258 /* FileViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileViewController.m; sourceTree = \"<group>\"; };\n\t\t87085FB71705D4AB009CD258 /* SmbAuthViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmbAuthViewController.h; sourceTree = \"<group>\"; };\n\t\t87085FB81705D4AB009CD258 /* SmbAuthViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SmbAuthViewController.m; sourceTree = \"<group>\"; };\n\t\t87085FB91705D4AB009CD258 /* TreeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TreeViewController.h; sourceTree = \"<group>\"; };\n\t\t87085FBA1705D4AB009CD258 /* TreeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TreeViewController.m; sourceTree = \"<group>\"; };\n\t\t87085FBF1705D4CA009CD258 /* libsmbclient.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsmbclient.a; path = libs/libsmbclient.a; sourceTree = \"<group>\"; };\n\t\t87085FC01705D4CA009CD258 /* libsmbclient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = libsmbclient.h; path = libs/libsmbclient.h; sourceTree = \"<group>\"; };\n\t\t87085FC11705D4CA009CD258 /* libtalloc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtalloc.a; path = libs/libtalloc.a; sourceTree = \"<group>\"; };\n\t\t87085FC21705D4CA009CD258 /* libtdb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtdb.a; path = libs/libtdb.a; sourceTree = \"<group>\"; };\n\t\t87085FC31705D4CA009CD258 /* libwbclient.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libwbclient.a; path = libs/libwbclient.a; sourceTree = \"<group>\"; };\n\t\t87085FC81705D4FD009CD258 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = \"compiled.mach-o.dylib\"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };\n\t\t87085FCA1705D503009CD258 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = \"compiled.mach-o.dylib\"; name = libiconv.dylib; path = usr/lib/libiconv.dylib; sourceTree = SDKROOT; };\n\t\t87085FCC1705D509009CD258 /* libresolv.dylib */ = {isa = PBXFileReference; lastKnownFileType = \"compiled.mach-o.dylib\"; name = libresolv.dylib; path = usr/lib/libresolv.dylib; sourceTree = SDKROOT; };\n\t\t871CC5581774489A00EDD76D /* talloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = talloc.h; path = libs/talloc.h; sourceTree = \"<group>\"; };\n\t\t871CC5591774491A00EDD76D /* talloc_stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = talloc_stack.h; path = libs/talloc_stack.h; sourceTree = \"<group>\"; };\n\t\t871CC5741774589C00EDD76D /* libKxSMB.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libKxSMB.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t871CC5781774589C00EDD76D /* KxSMB-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"KxSMB-Prefix.pch\"; sourceTree = \"<group>\"; };\n\t\tEAC6EFED179A4133005AC807 /* libtevent.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtevent.a; path = libs/libtevent.a; sourceTree = \"<group>\"; };\n\t\tF992AF0B1BC3D3CC0063A4B3 /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = System/Library/Frameworks/QuickLook.framework; sourceTree = SDKROOT; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t87085F861705D46C009CD258 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF992AF0C1BC3D3CC0063A4B3 /* QuickLook.framework in Frameworks */,\n\t\t\t\t87085FCD1705D509009CD258 /* libresolv.dylib in Frameworks */,\n\t\t\t\t87085FCB1705D503009CD258 /* libiconv.dylib in Frameworks */,\n\t\t\t\t87085FC91705D4FD009CD258 /* libz.dylib in Frameworks */,\n\t\t\t\t87085F8D1705D46C009CD258 /* UIKit.framework in Frameworks */,\n\t\t\t\t87085F8F1705D46C009CD258 /* Foundation.framework in Frameworks */,\n\t\t\t\t87085F911705D46C009CD258 /* CoreGraphics.framework in Frameworks */,\n\t\t\t\tEAC6EFEE179A4133005AC807 /* libtevent.a in Frameworks */,\n\t\t\t\t87085FC41705D4CA009CD258 /* libsmbclient.a in Frameworks */,\n\t\t\t\t87085FC51705D4CA009CD258 /* libtalloc.a in Frameworks */,\n\t\t\t\t87085FC61705D4CA009CD258 /* libtdb.a in Frameworks */,\n\t\t\t\t87085FC71705D4CA009CD258 /* libwbclient.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t871CC5711774589C00EDD76D /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t871CC5751774589C00EDD76D /* Foundation.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t87085F801705D46B009CD258 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t87085FB21705D494009CD258 /* KxSMBProvider.h */,\n\t\t\t\t87085FB31705D494009CD258 /* KxSMBProvider.m */,\n\t\t\t\t87085FBE1705D4BE009CD258 /* libs */,\n\t\t\t\t87085F921705D46C009CD258 /* KxSMBSample */,\n\t\t\t\t871CC5761774589C00EDD76D /* KxSMB */,\n\t\t\t\t87085F8B1705D46C009CD258 /* Frameworks */,\n\t\t\t\t87085F8A1705D46C009CD258 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t87085F8A1705D46C009CD258 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t87085F891705D46C009CD258 /* KxSMBSample.app */,\n\t\t\t\t871CC5741774589C00EDD76D /* libKxSMB.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t87085F8B1705D46C009CD258 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF992AF0B1BC3D3CC0063A4B3 /* QuickLook.framework */,\n\t\t\t\t87085FCC1705D509009CD258 /* libresolv.dylib */,\n\t\t\t\t87085FCA1705D503009CD258 /* libiconv.dylib */,\n\t\t\t\t87085FC81705D4FD009CD258 /* libz.dylib */,\n\t\t\t\t87085F8C1705D46C009CD258 /* UIKit.framework */,\n\t\t\t\t87085F8E1705D46C009CD258 /* Foundation.framework */,\n\t\t\t\t87085F901705D46C009CD258 /* CoreGraphics.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t87085F921705D46C009CD258 /* KxSMBSample */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t87085FB51705D4AB009CD258 /* FileViewController.h */,\n\t\t\t\t87085FB61705D4AB009CD258 /* FileViewController.m */,\n\t\t\t\t87085FB71705D4AB009CD258 /* SmbAuthViewController.h */,\n\t\t\t\t87085FB81705D4AB009CD258 /* SmbAuthViewController.m */,\n\t\t\t\t87085FB91705D4AB009CD258 /* TreeViewController.h */,\n\t\t\t\t87085FBA1705D4AB009CD258 /* TreeViewController.m */,\n\t\t\t\t87085F9B1705D46C009CD258 /* AppDelegate.h */,\n\t\t\t\t87085F9C1705D46C009CD258 /* AppDelegate.m */,\n\t\t\t\t87085F931705D46C009CD258 /* Supporting Files */,\n\t\t\t);\n\t\t\tpath = KxSMBSample;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t87085F931705D46C009CD258 /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t87085F941705D46C009CD258 /* KxSMBSample-Info.plist */,\n\t\t\t\t87085F951705D46C009CD258 /* InfoPlist.strings */,\n\t\t\t\t87085F981705D46C009CD258 /* main.m */,\n\t\t\t\t87085F9A1705D46C009CD258 /* KxSMBSample-Prefix.pch */,\n\t\t\t\t87085F9E1705D46C009CD258 /* Default.png */,\n\t\t\t\t87085FA01705D46C009CD258 /* Default@2x.png */,\n\t\t\t\t87085FA21705D46C009CD258 /* Default-568h@2x.png */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t87085FBE1705D4BE009CD258 /* libs */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t871CC5591774491A00EDD76D /* talloc_stack.h */,\n\t\t\t\t871CC5581774489A00EDD76D /* talloc.h */,\n\t\t\t\t87085FC01705D4CA009CD258 /* libsmbclient.h */,\n\t\t\t\t87085FBF1705D4CA009CD258 /* libsmbclient.a */,\n\t\t\t\t87085FC11705D4CA009CD258 /* libtalloc.a */,\n\t\t\t\t87085FC21705D4CA009CD258 /* libtdb.a */,\n\t\t\t\t87085FC31705D4CA009CD258 /* libwbclient.a */,\n\t\t\t\tEAC6EFED179A4133005AC807 /* libtevent.a */,\n\t\t\t);\n\t\t\tname = libs;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t871CC5761774589C00EDD76D /* KxSMB */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t871CC5771774589C00EDD76D /* Supporting Files */,\n\t\t\t);\n\t\t\tpath = KxSMB;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t871CC5771774589C00EDD76D /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t871CC5781774589C00EDD76D /* KxSMB-Prefix.pch */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t87085F881705D46C009CD258 /* KxSMBSample */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 87085FAF1705D46C009CD258 /* Build configuration list for PBXNativeTarget \"KxSMBSample\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t87085F851705D46C009CD258 /* Sources */,\n\t\t\t\t87085F861705D46C009CD258 /* Frameworks */,\n\t\t\t\t87085F871705D46C009CD258 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = KxSMBSample;\n\t\t\tproductName = KxSMBSample;\n\t\t\tproductReference = 87085F891705D46C009CD258 /* KxSMBSample.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\t871CC5731774589C00EDD76D /* KxSMB */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 871CC57F1774589C00EDD76D /* Build configuration list for PBXNativeTarget \"KxSMB\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t871CC5701774589C00EDD76D /* Sources */,\n\t\t\t\t871CC5711774589C00EDD76D /* Frameworks */,\n\t\t\t\t871CC5721774589C00EDD76D /* CopyFiles */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = KxSMB;\n\t\t\tproductName = KxSMB;\n\t\t\tproductReference = 871CC5741774589C00EDD76D /* libKxSMB.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t87085F811705D46B009CD258 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 0460;\n\t\t\t\tORGANIZATIONNAME = \"Konstantin Bukreev\";\n\t\t\t};\n\t\t\tbuildConfigurationList = 87085F841705D46B009CD258 /* Build configuration list for PBXProject \"KxSMBSample\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t);\n\t\t\tmainGroup = 87085F801705D46B009CD258;\n\t\t\tproductRefGroup = 87085F8A1705D46C009CD258 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t87085F881705D46C009CD258 /* KxSMBSample */,\n\t\t\t\t871CC5731774589C00EDD76D /* KxSMB */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t87085F871705D46C009CD258 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t87085F971705D46C009CD258 /* InfoPlist.strings in Resources */,\n\t\t\t\t87085F9F1705D46C009CD258 /* Default.png in Resources */,\n\t\t\t\t87085FA11705D46C009CD258 /* Default@2x.png in Resources */,\n\t\t\t\t87085FA31705D46C009CD258 /* Default-568h@2x.png in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t87085F851705D46C009CD258 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t87085F991705D46C009CD258 /* main.m in Sources */,\n\t\t\t\t87085F9D1705D46C009CD258 /* AppDelegate.m in Sources */,\n\t\t\t\t87085FB41705D494009CD258 /* KxSMBProvider.m in Sources */,\n\t\t\t\t87085FBB1705D4AB009CD258 /* FileViewController.m in Sources */,\n\t\t\t\t87085FBC1705D4AB009CD258 /* SmbAuthViewController.m in Sources */,\n\t\t\t\t87085FBD1705D4AB009CD258 /* TreeViewController.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t871CC5701774589C00EDD76D /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t871CC580177458AD00EDD76D /* KxSMBProvider.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t87085F951705D46C009CD258 /* InfoPlist.strings */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t87085F961705D46C009CD258 /* en */,\n\t\t\t);\n\t\t\tname = InfoPlist.strings;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t87085FAD1705D46C009CD258 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t87085FAE1705D46C009CD258 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tOTHER_CFLAGS = \"-DNS_BLOCK_ASSERTIONS=1\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t87085FB01705D46C009CD258 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = \"KxSMBSample/KxSMBSample-Prefix.pch\";\n\t\t\t\tHEADER_SEARCH_PATHS = \"\\\"$(SRCROOT)/libs\\\"\";\n\t\t\t\tINFOPLIST_FILE = \"KxSMBSample/KxSMBSample-Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"\\\"$(SRCROOT)/libs\\\"\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tUSER_HEADER_SEARCH_PATHS = \"\";\n\t\t\t\tWRAPPER_EXTENSION = app;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t87085FB11705D46C009CD258 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = \"KxSMBSample/KxSMBSample-Prefix.pch\";\n\t\t\t\tHEADER_SEARCH_PATHS = \"\\\"$(SRCROOT)/libs\\\"\";\n\t\t\t\tINFOPLIST_FILE = \"KxSMBSample/KxSMBSample-Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"\\\"$(SRCROOT)/libs\\\"\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tUSER_HEADER_SEARCH_PATHS = \"\";\n\t\t\t\tWRAPPER_EXTENSION = app;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t871CC57D1774589C00EDD76D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tDSTROOT = /tmp/KxSMB.dst;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = \"KxSMB/KxSMB-Prefix.pch\";\n\t\t\t\tHEADER_SEARCH_PATHS = \"\\\"$(SRCROOT)/libs\\\"\";\n\t\t\t\tOTHER_LDFLAGS = \"-ObjC\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tUSER_HEADER_SEARCH_PATHS = \"\\\"$(SRCROOT)/libs\\\"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t871CC57E1774589C00EDD76D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tDSTROOT = /tmp/KxSMB.dst;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = \"KxSMB/KxSMB-Prefix.pch\";\n\t\t\t\tHEADER_SEARCH_PATHS = \"\\\"$(SRCROOT)/libs\\\"\";\n\t\t\t\tOTHER_LDFLAGS = \"-ObjC\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tUSER_HEADER_SEARCH_PATHS = \"\\\"$(SRCROOT)/libs\\\"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t87085F841705D46B009CD258 /* Build configuration list for PBXProject \"KxSMBSample\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t87085FAD1705D46C009CD258 /* Debug */,\n\t\t\t\t87085FAE1705D46C009CD258 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t87085FAF1705D46C009CD258 /* Build configuration list for PBXNativeTarget \"KxSMBSample\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t87085FB01705D46C009CD258 /* Debug */,\n\t\t\t\t87085FB11705D46C009CD258 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t871CC57F1774589C00EDD76D /* Build configuration list for PBXNativeTarget \"KxSMB\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t871CC57D1774589C00EDD76D /* Debug */,\n\t\t\t\t871CC57E1774589C00EDD76D /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 87085F811705D46B009CD258 /* Project object */;\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2013 Konstantin Bukreev. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n \n- Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n \n- Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n \nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "Rakefile",
    "content": "# \n# Rakefile\n# kxsmb project\n# https://github.com/kolyvan/kxsmb/\n#\n# Created by Kolyvan on 29.03.13.\n#\n\n#\n# Copyright (c) 2013 Konstantin Bukreev All rights reserved.\n# \n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are met:\n# \n# - Redistributions of source code must retain the above copyright notice, this\n# list of conditions and the following disclaimer.\n# \n# - Redistributions in binary form must reproduce the above copyright notice,\n# this list of conditions and the following disclaimer in the documentation\n# and/or other materials provided with the distribution.\n# \n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n\nrequire \"pathname\"\nrequire \"fileutils\"\n\n# utils\n\ndef system_or_exit(cmd, stdout = nil)\n  puts \"Executing #{cmd}\"\n  cmd += \" >#{stdout}\" if stdout\n  system(cmd) or raise \"******** Build failed ********\"\nend\n\ndef copyIfNotExists(file, from, to)\n\n\tdest = Pathname.new(to)\n\tdest.mkdir unless dest.exist?\n\n\tunless (dest + file).exist?\n\t\tsource = Pathname.new(from) + file\n\t\tFileUtils.copy source, dest\t\n\t\tp \"copy #{source} -> #{dest}\"\n\tend\nend\n\ndef cleanOrMkDir(path)\n\tdest = Pathname.new path\n\tif dest.exist?\n\t\tFileUtils.rm Dir.glob(\"#{path}/*.a\")\n\telse\n\t\tdest.mkdir\n\tend\t\nend\n\ndef cleanDir(path)\n\tdest = Pathname.new path\n\tif dest.exist?\n\t\tFileUtils.rm Dir.glob(\"#{path}/*.a\")\t\n\tend\t\nend\n\n# versions\n\nIOS_MIN_VERSION='8.0'\nSAMBA_VERSION='4.0.26'\n\n# samba source\n\nSAMBA_BASE_URL=\"http://ftp.samba.org/pub/samba/stable/\"\n\n#pathes\n\nXCODE_PATH=%x{ /usr/bin/xcode-select --print-path }.delete(\"\\n\")\nSIM_SDK_PATH=XCODE_PATH + \"/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk\"\nIOS_SDK_PATH=XCODE_PATH + \"/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk\"\n\n#SAMBA_PATH=\"samba-#{SAMBA_VERSION}/source3\"\nSAMBA_FOLDER=\"samba\"\nSAMBA_SOURCE_PATH=\"#{SAMBA_FOLDER}/source3\"\nEXT_INCLUDE_PATH='tmp/include'\n\n# configure arguments\n\nCF_FLAGS='-pipe -Wno-trigraphs -fpascal-strings -Os -fembed-bitcode -g'\n\nIOS_CF_FLAGS='-ftree-vectorize'\nIOS_LD_FLAGS=''\n\nARM7_CF_FLAGS=\"-arch armv7 -mcpu=cortex-a8 -mfpu=neon #{IOS_CF_FLAGS} #{CF_FLAGS}\"\nARM7_LD_FLAGS=\"-arch armv7 #{IOS_LD_FLAGS}\"\n\nARM7s_CF_FLAGS=\"-arch armv7s -mcpu=cortex-a8 -mfpu=neon #{IOS_CF_FLAGS} #{CF_FLAGS}\"\nARM7s_LD_FLAGS=\"-arch armv7s #{IOS_LD_FLAGS}\"\n\nARM64_CF_FLAGS=\"-arch arm64 -Wno-error=implicit-function-declaration #{IOS_CF_FLAGS} #{CF_FLAGS}\"\nARM64_LD_FLAGS=\"-arch arm64 #{IOS_LD_FLAGS}\"\n\nI386_CF_FLAGS=\"-arch i386 #{CF_FLAGS}\"\nI386_LD_FLAGS='-arch i386'\n\nX86_64_CF_FLAGS=\"-arch x86_64 -Wno-error=implicit-function-declaration #{CF_FLAGS}\"\nX86_64_LD_FLAGS='-arch x86_64'\n\nSMB_ARGS = [\n'--prefix=/private',\n'--disable-shared',\n'--enable-static',\n'--without-readline',\n'--with-libsmbclient',\n'--without-libnetapi',\n'--without-libsmbsharemodes',\n'--without-cluster-support',\n'--without-ldap',\n'--disable-swat',\n'--disable-cups',\n'--disable-iprint',\n'libreplace_cv_HAVE_C99_VSNPRINTF=yes',\n'samba_cv_CC_NEGATIVE_ENUM_VALUES=yes',\n]\n\nSIM_SMB_ARGS = [\n'--enable-debug',\n'samba_cv_HAVE_FCNTL_LOCK=yes'\n]\n\nIOS_SMB_ARGS = [\n'ac_cv_header_libunwind_h=no',\n'ac_cv_header_execinfo_h=no',\n'ac_cv_header_rpcsvc_ypclnt_h=no',\n'ac_cv_file__proc_sys_kernel_core_pattern=no',\n'ac_cv_func_fdatasync=no',\n'libreplace_cv_HAVE_GETADDRINFO=no',\n'samba_cv_SYSCONF_SC_NPROCESSORS_ONLN=no',\n'samba_cv_big_endian=no',\n'samba_cv_little_endian=yes',\n]\n\nARM7_SMB_ARGS = [\n'--host=arm-apple-darwin',\n]\n\nARM7s_SMB_ARGS = [\n'--host=arm-apple-darwin',\n]\n\nARM64_SMB_ARGS = [\n'--host=arm-apple-darwin',\n]\n\nI386_SMB_ARGS = [\n'--host=i686-apple-darwin',\n]\n\nX86_64_SMB_ARGS = [\n'--host=x86_64-apple-darwin',\n]\n\n# libs\n\nSMB_LIBS = [\n'libsmbclient',\n'libtalloc',\n'libtevent',\n'libtdb',\n'libwbclient',\n]\n\n# functions\n\ndef mkArgs(sdkPath, platformArgs, procArgs, cfFlags, ldFlags)\n\n\textInclude = Pathname.new(EXT_INCLUDE_PATH).realpath\n\n\targs = SMB_ARGS + platformArgs + procArgs\n\tENV['AR']=\"xcrun ar\"\n\tENV['CC']=\"xcrun clang\"\n\tENV['CPP']=\"xcrun clang -E\"\n\tENV['LD']=\"xcrun ld\"\n\tENV['CFLAGS']=\"-std=gnu99 -no-cpp-precomp -miphoneos-version-min=#{IOS_MIN_VERSION} -isysroot #{sdkPath} -I#{sdkPath}/usr/include #{cfFlags}\"\n\tENV['CPPFLAGS']=\"-std=gnu99 -no-cpp-precomp -miphoneos-version-min=#{IOS_MIN_VERSION} -isysroot #{sdkPath} -I#{sdkPath}/usr/include #{cfFlags} -I#{extInclude}\"\n\tENV['LDFLAGS']=\"-miphoneos-version-min=#{IOS_MIN_VERSION} -isysroot #{sdkPath} -L#{sdkPath}/usr/lib #{ldFlags}\"\n\targs.join(' ')\nend\n\ndef buildArch(arch)\n\n\tcase arch\n\twhen 'i386'\n\t\targs = mkArgs(SIM_SDK_PATH, SIM_SMB_ARGS, I386_SMB_ARGS, I386_CF_FLAGS, I386_LD_FLAGS)\n\twhen 'armv7'\n\t\targs = mkArgs(IOS_SDK_PATH, IOS_SMB_ARGS, ARM7_SMB_ARGS, ARM7_CF_FLAGS, ARM7_LD_FLAGS)\n\twhen 'armv7s'\t\n\t\targs = mkArgs(IOS_SDK_PATH, IOS_SMB_ARGS, ARM7s_SMB_ARGS, ARM7s_CF_FLAGS, ARM7s_LD_FLAGS)\n\twhen 'arm64'\t\n\t\targs = mkArgs(IOS_SDK_PATH, IOS_SMB_ARGS, ARM64_SMB_ARGS, ARM64_CF_FLAGS, ARM64_LD_FLAGS)\n\twhen 'x86_64'\n\t\targs = mkArgs(SIM_SDK_PATH, SIM_SMB_ARGS, X86_64_SMB_ARGS, X86_64_CF_FLAGS, X86_64_LD_FLAGS)\n\telse\n\t\traise \"Build failed: unknown arch: #{arch}\"\n\tend\n\t\n\tp args\n\t\n\tsystem_or_exit \"cd #{SAMBA_SOURCE_PATH}; ./autogen.sh\"\n\tsystem_or_exit \"cd #{SAMBA_SOURCE_PATH}; ./configure #{args}\"\n\n\tSMB_LIBS.each do |x|\n\t\tsystem_or_exit \"cd #{SAMBA_SOURCE_PATH}; make #{x}\"\t\t\n\tend\t\n\n\tdest = Pathname.new(\"#{SAMBA_SOURCE_PATH}/bin/#{arch}\")\t\n\tcleanOrMkDir(dest)\n\n\tSMB_LIBS.each do |x|\n\t\tFileUtils.move Pathname.new(\"#{SAMBA_SOURCE_PATH}/bin/#{x}.a\"), dest\t\t\n\tend\n\n\tsystem_or_exit \"cd #{SAMBA_SOURCE_PATH}; make clean\"\nend\n\ndef checkExtInclude\n\textInclude = Pathname.new(EXT_INCLUDE_PATH)\n\textInclude.mkpath unless extInclude.exist?\t \n\tcopyIfNotExists('crt_externs.h', \"#{SIM_SDK_PATH}/usr/include/\", extInclude.realpath)\nend\n\n# tasks\n\ndesc \"Build smb armv7 libs\"\ntask :build_smb_armv7 do\n\tcheckExtInclude\t\n\tbuildArch('armv7')\t\nend\n\ndesc \"Build smb armv7s libs\"\ntask :build_smb_armv7s do\n\tcheckExtInclude\t\n\tbuildArch('armv7s')\t\nend\n\ndesc \"Build smb arm64 libs\"\ntask :build_smb_arm64 do\n\tcheckExtInclude\t\n\tbuildArch('arm64')\t\nend\n\ndesc \"Build smb i386 libs\"\ntask :build_smb_i386 do\t\n\tbuildArch('i386')\t\nend\n\ndesc \"Build smb x86_64 libs\"\ntask :build_smb_x86_64 do\t\n\tbuildArch('x86_64')\t\nend\n\ndesc \"Build smb universal libs (full)\"\ntask :build_smb_universal_full do\t\n\t\n\tdest = Pathname.new(\"#{SAMBA_SOURCE_PATH}/bin/universal\")\n\tdest.mkdir unless dest.exist?\n\n\tSMB_LIBS.each do |x|\n\t\targs = \"-create -arch armv7 #{SAMBA_SOURCE_PATH}/bin/armv7/#{x}.a -arch armv7s #{SAMBA_SOURCE_PATH}/bin/armv7s/#{x}.a -arch arm64 #{SAMBA_SOURCE_PATH}/bin/arm64/#{x}.a -arch i386 #{SAMBA_SOURCE_PATH}/bin/i386/#{x}.a -arch x86_64 #{SAMBA_SOURCE_PATH}/bin/x86_64/#{x}.a -output #{dest}/#{x}.a\"\n\t\tsystem_or_exit \"xcrun lipo #{args}\"\n\tend\t\nend\n\ndesc \"Build smb universal libs\"\ntask :build_smb_universal do\t\n\t\n\tdest = Pathname.new(\"#{SAMBA_SOURCE_PATH}/bin/universal\")\n\tdest.mkdir unless dest.exist?\n\n\tSMB_LIBS.each do |x|\n\t\targs = \"-create -arch armv7 #{SAMBA_SOURCE_PATH}/bin/armv7/#{x}.a -arch arm64 #{SAMBA_SOURCE_PATH}/bin/arm64/#{x}.a -arch i386 #{SAMBA_SOURCE_PATH}/bin/i386/#{x}.a -arch x86_64 #{SAMBA_SOURCE_PATH}/bin/x86_64/#{x}.a -output #{dest}/#{x}.a\"\n\t\tsystem_or_exit \"xcrun lipo #{args}\"\n\tend\t\nend\n\ndesc \"Copy smb headers\"\ntask :copy_headers do\t\t\n\tcopyIfNotExists('libsmbclient.h', \"#{SAMBA_SOURCE_PATH}/include/\", 'libs')\n\tcopyIfNotExists('talloc.h', \"#{SAMBA_FOLDER}/lib/talloc/\", 'libs')\n\tcopyIfNotExists('talloc_stack.h', \"#{SAMBA_FOLDER}/lib/util/\", 'libs')\nend\t\n\ndesc \"Copy smb libs\"\ntask :copy_libs do\t\t\n\t\n\tdest = Pathname.new('libs')\n\tdest.mkdir unless dest.exist?\n\n\tfrom = Pathname.new(\"#{SAMBA_SOURCE_PATH}/bin/universal\")\n\n\tSMB_LIBS.each do |x|\n\t\tsource = from + \"#{x}.a\"\n\t\tFileUtils.move source, dest\t\n\t\tp \"copy #{source} -> #{dest}\"\n\tend\nend\t\n\ndesc \"Clean\"\ntask :clean do\n\tcleanDir(\"#{SAMBA_SOURCE_PATH}/bin/armv7\")\n\tcleanDir(\"#{SAMBA_SOURCE_PATH}/bin/armv7s\")\n\tcleanDir(\"#{SAMBA_SOURCE_PATH}/bin/arm64\")\n\tcleanDir(\"#{SAMBA_SOURCE_PATH}/bin/i386\")\n\tcleanDir(\"#{SAMBA_SOURCE_PATH}/bin/x86_64\")\t\n\tcleanDir(\"#{SAMBA_SOURCE_PATH}/bin/universal\")\t\n\n\tsystem_or_exit \"cd #{SAMBA_SOURCE_PATH}; make clean\"\t\nend\n\ndesc \"Retrieve samble archive\"\ntask :retrieve_samba do\n\n\tp = Pathname.new \"#{SAMBA_SOURCE_PATH}\"\n \tunless p.exist?\n\n \t\tname = \"samba-#{SAMBA_VERSION}\"\n \t\tfile = \"#{name}.tar.gz\"\n\t\turl = \"#{SAMBA_BASE_URL}#{file}\"\n\n \t\tp \"retrieving samba from #{url}\"\n\t\tsystem_or_exit \"/usr/bin/curl -L --output #{file} #{url}\"\n\n\t\tp \"extracting samba from archive\"\n\t\tsystem_or_exit \"tar -zxf #{file}\"\n\n\t\tPathname.new(file).delete\n\t\tPathname.new(name).rename SAMBA_FOLDER\n \tend\n\nend\n\ntask :build_full => [:retrieve_samba, :build_smb_armv7, :build_smb_armv7s, :build_smb_arm64, :build_smb_i386, :build_smb_x86_64, :build_smb_universal_full, :copy_libs, :copy_headers] \ntask :build_all => [:retrieve_samba, :build_smb_armv7, :build_smb_arm64, :build_smb_i386, :build_smb_x86_64, :build_smb_universal, :copy_libs, :copy_headers] \ntask :default => [:build_all]\n"
  },
  {
    "path": "readme.md",
    "content": "KxSMB is objective-c wrapper for libsmbclient lib. \n===========================================\n\nFor now KxSMB supports a limited set of SMB operations.\nIt mostly was designed for browsing local net and retrieving files.\n\n### Build instructions:\n\nFirst you need download, configure and build [samba](http://www.samba.org).\nFor this open console and type in\n\t\n\tcd kxsmb\t\n\trake\n\n### Usage\n\n1. Drop files from kxsmb/libs folder in your project.\n2. Add libs: libz.dylib, libresolv.dylib and liconv.dylib.\n\nFetching a folder content:\n\n\tNSArray *items = [[KxSMBProvider sharedSmbProvider] fetchAtPath: @\"smb://server/share/\"];\n\nReading a file:\n\n\tKxSMBItemFile *file = [[KxSMBProvider sharedSmbProvider] fetchAtPath: @\"smb://server/share/file\"];\n\tNSData *data = [file readDataToEndOfFile];\n\nLook at kxSMBSample demo project as example of using.\n\n### Requirements\n\nat least iOS 5.0 and Xcode 4.5.0\n\n### License\n\nkxsmb is open source and covered by a standard 2-clause BSD license. See the LICENSE file for more info.\n\n[Samba](http://www.samba.org) is [Free Software](http://www.gnu.org/philosophy/free-sw.html) licensed under the [GNU General Public License](http://www.samba.org/samba/docs/GPL.html).\n\n### Feedback\n\nTweet me — [@kolyvan_ru](http://twitter.com/kolyvan_ru)."
  }
]