Smb4K – Samba (SMB) share advanced browser
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

1560 lines
39KB

  1. /***************************************************************************
  2. smb4ksambaoptionshandler - This class handles the Samba options.
  3. -------------------
  4. begin : So Mai 14 2006
  5. copyright : (C) 2006-2007 by Alexander Reinholdt
  6. email : dustpuppy@users.berlios.de
  7. ***************************************************************************/
  8. /***************************************************************************
  9. * This program is free software; you can redistribute it and/or modify *
  10. * it under the terms of the GNU General Public License as published by *
  11. * the Free Software Foundation; either version 2 of the License, or *
  12. * (at your option) any later version. *
  13. * *
  14. * This program is distributed in the hope that it will be useful, but *
  15. * WITHOUT ANY WARRANTY; without even the implied warranty of *
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
  17. * General Public License for more details. *
  18. * *
  19. * You should have received a copy of the GNU General Public License *
  20. * along with this program; if not, write to the *
  21. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
  22. * MA 02110-1301 USA *
  23. ***************************************************************************/
  24. // TQt includes
  25. #include <tqfile.h>
  26. #include <tqtextstream.h>
  27. #include <tqdir.h>
  28. // KDE includes
  29. #include <kstandarddirs.h>
  30. #include <kprocess.h>
  31. #include <kdebug.h>
  32. #include <klocale.h>
  33. // system specific includes
  34. #include <unistd.h>
  35. #include <sys/types.h>
  36. #include <errno.h>
  37. // application specific includes
  38. #include "smb4ksambaoptionshandler.h"
  39. #include "smb4kdefs.h"
  40. #include "smb4kerror.h"
  41. #include "smb4kglobal.h"
  42. #include "smb4ksambaoptionsinfo.h"
  43. #include "smb4kshare.h"
  44. #include "smb4ksettings.h"
  45. using namespace Smb4KGlobal;
  46. Smb4KSambaOptionsHandler::Smb4KSambaOptionsHandler( TQObject *parent, const char *name )
  47. : TQObject( parent, name )
  48. {
  49. // We need the directory.
  50. KStandardDirs *stddir = new KStandardDirs();
  51. TQString dir = locateLocal( "data", "smb4k", KGlobal::instance() );
  52. if ( !stddir->exists( dir ) )
  53. {
  54. stddir->makeDir( dir );
  55. }
  56. delete stddir;
  57. m_wins_server = TQString();
  58. }
  59. Smb4KSambaOptionsHandler::~Smb4KSambaOptionsHandler()
  60. {
  61. for ( TQValueList<Smb4KSambaOptionsInfo *>::Iterator it = m_list.begin();
  62. it != m_list.end(); ++it )
  63. {
  64. delete *it;
  65. }
  66. m_list.clear();
  67. }
  68. const TQValueList<Smb4KSambaOptionsInfo *> &Smb4KSambaOptionsHandler::customOptionsList()
  69. {
  70. if ( m_list.isEmpty() )
  71. {
  72. read_options();
  73. }
  74. return m_list;
  75. }
  76. void Smb4KSambaOptionsHandler::read_options()
  77. {
  78. // Clear the list before filling it (again)
  79. if ( !m_list.isEmpty() )
  80. {
  81. for ( TQValueList<Smb4KSambaOptionsInfo *>::Iterator it = m_list.begin();
  82. it != m_list.end(); ++it )
  83. {
  84. delete *it;
  85. }
  86. m_list.clear();
  87. }
  88. TQFile file( locateLocal( "data", "smb4k/custom_options", KGlobal::instance() ) );
  89. TQStringList contents;
  90. if ( file.open( IO_ReadOnly ) )
  91. {
  92. TQTextStream ts( &file );
  93. ts.setEncoding( TQTextStream::Locale );
  94. contents = TQStringList::split( '\n', ts.read(), true );
  95. file.close();
  96. }
  97. else
  98. {
  99. if ( file.exists() )
  100. {
  101. Smb4KError::error( ERROR_READING_FILE, file.name() );
  102. }
  103. return;
  104. }
  105. if ( !contents.isEmpty() )
  106. {
  107. for ( TQStringList::ConstIterator it = contents.begin(); it != contents.end(); ++it )
  108. {
  109. if ( (*it).startsWith( "[" ) )
  110. {
  111. Smb4KSambaOptionsInfo *info = new Smb4KSambaOptionsInfo( (*it).section( "[", 1, -1 ).section( "]", -2, 0 ) );
  112. for ( TQStringList::ConstIterator i = ++it; i != contents.end(); ++i )
  113. {
  114. if ( (*i).startsWith( "remount=" ) )
  115. {
  116. bool remount = TQString::compare( (*i).section( "=", 1, 1 ).stripWhiteSpace(), "true" ) == 0 ? true : false;
  117. info->setRemount( remount );
  118. continue;
  119. }
  120. else if ( (*i).startsWith( "port=" ) )
  121. {
  122. int port = (*i).section( "=", 1, 1 ).stripWhiteSpace().toInt();
  123. info->setPort( port );
  124. continue;
  125. }
  126. #ifndef __FreeBSD__
  127. else if ( (*i).startsWith( "filesystem=" ) )
  128. {
  129. info->setFilesystem( (*i).section( "=", 1, 1 ).stripWhiteSpace() );
  130. continue;
  131. }
  132. else if ( (*i).startsWith( "read-write=" ) ) // Deprecated since version 0.9.0
  133. {
  134. info->setWriteAccess( TQString::compare( (*i).section( "=", 1, 1 ).stripWhiteSpace(), "true" ) == 0 );
  135. continue;
  136. }
  137. else if ( (*i).startsWith( "write access=" ) )
  138. {
  139. info->setWriteAccess( TQString::compare( (*i).section( "=", 1, 1 ).stripWhiteSpace(), "true" ) == 0 );
  140. continue;
  141. }
  142. #endif
  143. else if ( (*i).startsWith( "protocol=" ) )
  144. {
  145. info->setProtocol( (*i).section( "=", 1, 1 ).stripWhiteSpace() );
  146. continue;
  147. }
  148. else if ( (*i).startsWith( "kerberos=" ) )
  149. {
  150. info->setKerberos( TQString::compare( (*i).section( "=", 1, 1 ).stripWhiteSpace(), "true" ) == 0 );
  151. continue;
  152. }
  153. else if ( (*i).startsWith( "uid=" ) )
  154. {
  155. info->setUID( (*i).section( "=", 1, 1 ).stripWhiteSpace() );
  156. continue;
  157. }
  158. else if ( (*i).startsWith( "gid=" ) )
  159. {
  160. info->setGID( (*i).section( "=", 1, 1 ).stripWhiteSpace() );
  161. continue;
  162. }
  163. else if ( (*i).isEmpty() || (*i).stripWhiteSpace().startsWith( "[" ) )
  164. {
  165. it = i;
  166. break;
  167. }
  168. else
  169. {
  170. continue;
  171. }
  172. }
  173. m_list.append( info );
  174. }
  175. else
  176. {
  177. continue;
  178. }
  179. }
  180. }
  181. }
  182. void Smb4KSambaOptionsHandler::write_options()
  183. {
  184. TQString protocol_hint;
  185. // Determine the protocol hint specified by the user:
  186. switch ( Smb4KSettings::protocolHint() )
  187. {
  188. case Smb4KSettings::EnumProtocolHint::Automatic:
  189. {
  190. // In this case the user leaves it to the net
  191. // command to determine the right protocol.
  192. protocol_hint = TQString();
  193. break;
  194. }
  195. case Smb4KSettings::EnumProtocolHint::RPC:
  196. {
  197. protocol_hint = "rpc";
  198. break;
  199. }
  200. case Smb4KSettings::EnumProtocolHint::RAP:
  201. {
  202. protocol_hint = "rap";
  203. break;
  204. }
  205. case Smb4KSettings::EnumProtocolHint::ADS:
  206. {
  207. protocol_hint = "ads";
  208. break;
  209. }
  210. default:
  211. {
  212. protocol_hint = TQString();
  213. break;
  214. }
  215. }
  216. #ifndef __FreeBSD__
  217. TQString default_filesystem;
  218. switch( Smb4KSettings::filesystem() )
  219. {
  220. case Smb4KSettings::EnumFilesystem::CIFS:
  221. {
  222. default_filesystem = "cifs";
  223. break;
  224. }
  225. case Smb4KSettings::EnumFilesystem::SMBFS:
  226. {
  227. default_filesystem = "smbfs";
  228. break;
  229. }
  230. default:
  231. {
  232. // FIXME: Set default_filesystem to "cifs"?
  233. break;
  234. }
  235. }
  236. bool write_access = true;
  237. switch( Smb4KSettings::writeAccess() )
  238. {
  239. case Smb4KSettings::EnumWriteAccess::ReadWrite:
  240. {
  241. write_access = true;
  242. break;
  243. }
  244. case Smb4KSettings::EnumWriteAccess::ReadOnly:
  245. {
  246. write_access = false;
  247. break;
  248. }
  249. default:
  250. {
  251. break;
  252. }
  253. }
  254. #endif
  255. TQFile file( locateLocal( "data", "smb4k/custom_options", KGlobal::instance() ) );
  256. if ( !m_list.isEmpty() )
  257. {
  258. if ( file.open( IO_WriteOnly ) )
  259. {
  260. TQTextStream ts( &file );
  261. ts.setEncoding( TQTextStream::Locale );
  262. for ( TQValueList<Smb4KSambaOptionsInfo *>::ConstIterator it = m_list.begin(); it != m_list.end(); ++it )
  263. {
  264. switch ( (*it)->type() )
  265. {
  266. case Smb4KSambaOptionsInfo::Host:
  267. {
  268. // Check if we need to write anything:
  269. if ( (*it)->port() != -1 ||
  270. !(*it)->protocol().stripWhiteSpace().isEmpty() ||
  271. ((*it)->kerberos() != Smb4KSettings::useKerberos()) )
  272. {
  273. ts << "[" << (*it)->itemName() << "]" << endl;
  274. ts << "port=" << ((*it)->port() != -1 ? (*it)->port() :
  275. Smb4KSettings::remotePort()) << endl;
  276. ts << "kerberos=" << ((*it)->kerberos() ? "true" : "false") << endl;
  277. ts << "protocol=" << (!(*it)->protocol().stripWhiteSpace().isEmpty() ?
  278. (*it)->protocol() : protocol_hint) << endl;
  279. }
  280. else
  281. {
  282. // Do nothing
  283. }
  284. break;
  285. }
  286. case Smb4KSambaOptionsInfo::Share:
  287. {
  288. if ( (*it)->port() != -1 ||
  289. (*it)->remount() ||
  290. #ifndef __FreeBSD__
  291. (*it)->kerberos() != Smb4KSettings::useKerberos() ||
  292. !(*it)->filesystem().isEmpty() ||
  293. (*it)->writeAccess() != write_access ||
  294. #endif
  295. !(*it)->uid().isEmpty() ||
  296. !(*it)->gid().isEmpty() )
  297. {
  298. ts << "[" << (*it)->itemName() << "]" << endl;
  299. ts << "port=" << ((*it)->port() != -1 ? (*it)->port() :
  300. Smb4KSettings::remotePort()) << endl;
  301. ts << "remount=" << ((*it)->remount() ? "true" : "false") << endl;
  302. #ifndef __FreeBSD__
  303. // FreeBSD does not know Kerberos for mounting:
  304. ts << "kerberos=" << ((*it)->kerberos() ? "true" : "false") << endl;
  305. ts << "filesystem=" << (!(*it)->filesystem().stripWhiteSpace().isEmpty() ?
  306. (*it)->filesystem() : default_filesystem) << endl;
  307. ts << "write access=" << ((*it)->writeAccess() ? "true" : "false") << endl;
  308. #endif
  309. ts << "uid=" << (!(*it)->uid().stripWhiteSpace().isEmpty() ?
  310. (*it)->uid() : Smb4KSettings::userID()) << endl;
  311. ts << "gid=" << (!(*it)->gid().stripWhiteSpace().isEmpty() ?
  312. (*it)->gid() : Smb4KSettings::groupID()) << endl;
  313. }
  314. else
  315. {
  316. // Do nothing
  317. }
  318. break;
  319. }
  320. default:
  321. {
  322. break;
  323. }
  324. }
  325. ts << endl;
  326. }
  327. file.close();
  328. }
  329. }
  330. else
  331. {
  332. file.remove();
  333. }
  334. }
  335. void Smb4KSambaOptionsHandler::remount( Smb4KShare *share, bool yes )
  336. {
  337. if ( share )
  338. {
  339. Smb4KSambaOptionsInfo *info = NULL;
  340. if ( (info = find_item( share->name() )) )
  341. {
  342. info->setRemount( yes );
  343. }
  344. else if ( !info && yes )
  345. {
  346. info = new Smb4KSambaOptionsInfo( share );
  347. info->setRemount( yes );
  348. m_list.append( info );
  349. }
  350. }
  351. }
  352. void Smb4KSambaOptionsHandler::sync()
  353. {
  354. write_options();
  355. }
  356. Smb4KSambaOptionsInfo *Smb4KSambaOptionsHandler::find_item( const TQString &item, bool exactMatch )
  357. {
  358. // If the list is empty, we'll read the file.
  359. if ( m_list.isEmpty() )
  360. {
  361. read_options();
  362. }
  363. TQString host = item.section( "/", 2, 2 ).stripWhiteSpace();
  364. Smb4KSambaOptionsInfo *info = NULL;
  365. if ( !item.stripWhiteSpace().isEmpty() )
  366. {
  367. for ( TQValueList<Smb4KSambaOptionsInfo *>::ConstIterator it = m_list.begin();
  368. it != m_list.end(); ++it )
  369. {
  370. if ( TQString::compare( item.lower(), (*it)->itemName().lower() ) == 0 )
  371. {
  372. info = *it;
  373. break;
  374. }
  375. else if ( TQString::compare( host.lower(), (*it)->itemName().lower() ) == 0 )
  376. {
  377. if ( !info && !exactMatch )
  378. {
  379. info = *it;
  380. }
  381. continue;
  382. }
  383. else
  384. {
  385. continue;
  386. }
  387. }
  388. }
  389. return info;
  390. }
  391. const TQString Smb4KSambaOptionsHandler::smbclientOptions( const TQString &share )
  392. {
  393. // Get the global Samba options
  394. (void) globalSambaOptions();
  395. Smb4KSambaOptionsInfo *info = find_item( share );
  396. TQString args = TQString();
  397. // Get the strings that are needed to put the
  398. // argument list together:
  399. TQString resolve_order = (!Smb4KSettings::nameResolveOrder().isEmpty() &&
  400. TQString::compare( Smb4KSettings::nameResolveOrder(),
  401. m_samba_options["name resolve order"] ) != 0) ?
  402. Smb4KSettings::nameResolveOrder() :
  403. TQString();
  404. TQString netbios_name = (!Smb4KSettings::netBIOSName().isEmpty() &&
  405. TQString::compare( Smb4KSettings::netBIOSName(),
  406. m_samba_options["netbios name"] ) != 0) ?
  407. Smb4KSettings::netBIOSName() :
  408. TQString();
  409. TQString netbios_scope = (!Smb4KSettings::netBIOSScope().isEmpty() &&
  410. TQString::compare( Smb4KSettings::netBIOSScope(),
  411. m_samba_options["netbios scope"] ) != 0) ?
  412. Smb4KSettings::netBIOSScope() :
  413. TQString();
  414. TQString socket_options = (!Smb4KSettings::socketOptions().isEmpty() &&
  415. TQString::compare( Smb4KSettings::socketOptions(),
  416. m_samba_options["socket options"] ) != 0) ?
  417. Smb4KSettings::socketOptions() :
  418. TQString();
  419. bool kerberos = info ?
  420. info->kerberos() :
  421. Smb4KSettings::useKerberos();
  422. int port = info && info->port() != -1 ?
  423. info->port() :
  424. Smb4KSettings::remotePort();
  425. // Options that are not customizable:
  426. args.append( !resolve_order.isEmpty() ?
  427. TQString( " -R '%1'" ).tqarg( resolve_order ) :
  428. TQString() );
  429. args.append( !netbios_name.isEmpty() ?
  430. TQString( " -n '%1'" ).tqarg( netbios_name ) :
  431. TQString() );
  432. args.append( !netbios_scope.isEmpty() ?
  433. TQString( " -i '%1'" ).tqarg( netbios_scope ) :
  434. TQString() );
  435. args.append( !socket_options.isEmpty() ?
  436. TQString( " -O '%1'" ).tqarg( socket_options ) :
  437. TQString() );
  438. args.append( Smb4KSettings::bufferSize() != 65520 ?
  439. TQString( " -b %1" ).tqarg( Smb4KSettings::bufferSize() ) :
  440. TQString() );
  441. args.append( Smb4KSettings::machineAccount() ? " -P" : TQString() );
  442. switch ( Smb4KSettings::signingState() )
  443. {
  444. case Smb4KSettings::EnumSigningState::None:
  445. {
  446. // The user does not want this setting
  447. // to be used.
  448. break;
  449. }
  450. case Smb4KSettings::EnumSigningState::On:
  451. {
  452. args.append( " -S on" );
  453. break;
  454. }
  455. case Smb4KSettings::EnumSigningState::Off:
  456. {
  457. args.append( " -S off" );
  458. break;
  459. }
  460. case Smb4KSettings::EnumSigningState::Required:
  461. {
  462. args.append( " -S required" );
  463. break;
  464. }
  465. default:
  466. {
  467. break;
  468. }
  469. }
  470. args.append( kerberos ? " -k" : TQString() );
  471. args.append( TQString( " -p %1" ).tqarg( port ) );
  472. return args;
  473. }
  474. const TQString Smb4KSambaOptionsHandler::nmblookupOptions( bool with_broadcast )
  475. {
  476. // Get the global Samba options
  477. (void) globalSambaOptions();
  478. TQString args = TQString();
  479. TQString netbios_name = (!Smb4KSettings::netBIOSName().isEmpty() &&
  480. TQString::compare( Smb4KSettings::netBIOSName(),
  481. m_samba_options["netbios name"] ) != 0) ?
  482. Smb4KSettings::netBIOSName() :
  483. TQString();
  484. TQString netbios_scope = (!Smb4KSettings::netBIOSScope().isEmpty() &&
  485. TQString::compare( Smb4KSettings::netBIOSScope(),
  486. m_samba_options["netbios scope"] ) != 0) ?
  487. Smb4KSettings::netBIOSScope() :
  488. TQString();
  489. TQString socket_options = (!Smb4KSettings::socketOptions().isEmpty() &&
  490. TQString::compare( Smb4KSettings::socketOptions(),
  491. m_samba_options["socket options"] ) != 0) ?
  492. Smb4KSettings::socketOptions() :
  493. TQString();
  494. TQString domain = (!Smb4KSettings::domainName().isEmpty() &&
  495. TQString::compare( Smb4KSettings::domainName(),
  496. m_samba_options["workgroup"] ) != 0) ?
  497. Smb4KSettings::domainName() :
  498. TQString();
  499. args.append( !netbios_name.isEmpty() ?
  500. TQString( " -n '%1'" ).tqarg( netbios_name ) :
  501. TQString() );
  502. args.append( !netbios_scope.isEmpty() ?
  503. TQString( " -i '%1'" ).tqarg( netbios_scope ) :
  504. TQString() );
  505. args.append( !socket_options.isEmpty() ?
  506. TQString( " -O '%1'" ).tqarg( socket_options ) :
  507. TQString() );
  508. args.append( !domain.isEmpty() ?
  509. TQString( " -W '%1'" ).tqarg( domain ) :
  510. TQString() );
  511. args.append( (!Smb4KSettings::broadcastAddress().isEmpty() &&
  512. with_broadcast) ?
  513. TQString( " -B %1" ).tqarg( Smb4KSettings::broadcastAddress() ) :
  514. TQString() );
  515. args.append( Smb4KSettings::usePort137() ?
  516. " -r" :
  517. TQString() );
  518. return args;
  519. }
  520. const TQString Smb4KSambaOptionsHandler::netOptions( int command, const TQString &networkItem, const TQString &protocol )
  521. {
  522. TQString args = TQString();
  523. Smb4KSambaOptionsInfo *info = find_item( networkItem );
  524. TQString protocol_hint;
  525. // Determine the protocol hint specified by the user:
  526. switch ( Smb4KSettings::protocolHint() )
  527. {
  528. case Smb4KSettings::EnumProtocolHint::Automatic:
  529. {
  530. // In this case the user leaves it to the net
  531. // command to determine the right protocol.
  532. protocol_hint = TQString();
  533. break;
  534. }
  535. case Smb4KSettings::EnumProtocolHint::RPC:
  536. {
  537. protocol_hint = "rpc";
  538. break;
  539. }
  540. case Smb4KSettings::EnumProtocolHint::RAP:
  541. {
  542. protocol_hint = "rap";
  543. break;
  544. }
  545. case Smb4KSettings::EnumProtocolHint::ADS:
  546. {
  547. protocol_hint = "ads";
  548. break;
  549. }
  550. default:
  551. {
  552. protocol_hint = TQString();
  553. break;
  554. }
  555. }
  556. TQString default_protocol = (info && !info->protocol().isEmpty()) ?
  557. info->protocol() :
  558. protocol_hint;
  559. TQString netbios_name = (!Smb4KSettings::netBIOSName().isEmpty() &&
  560. TQString::compare( Smb4KSettings::netBIOSName(),
  561. m_samba_options["netbios name"] ) != 0) ?
  562. Smb4KSettings::netBIOSName() :
  563. TQString();
  564. TQString domain = (!Smb4KSettings::domainName().isEmpty() &&
  565. TQString::compare( Smb4KSettings::domainName(),
  566. m_samba_options["workgroup"] ) != 0) ?
  567. Smb4KSettings::domainName() :
  568. TQString();
  569. int port = (info && info->port() != -1) ?
  570. info->port() :
  571. Smb4KSettings::remotePort();
  572. // Add command specific arguments:
  573. switch ( command )
  574. {
  575. case Share:
  576. {
  577. // We can only use the RAP or RPC protocol here.
  578. if ( !protocol.stripWhiteSpace().isEmpty() )
  579. {
  580. // Protocol can only be defined by us developers,
  581. // and we should know what we are doing. So, no
  582. // checks for the right protocol here:
  583. args.append( TQString( " %1" ).tqarg( protocol ) );
  584. }
  585. else
  586. {
  587. args.append( TQString( " %1" ).tqarg( TQString::compare( default_protocol, "ads" ) != 0 ?
  588. default_protocol :
  589. TQString() /* FIXME: Is that the best way how to do it? */) );
  590. }
  591. args.append( " share -l" );
  592. break;
  593. }
  594. case ServerDomain:
  595. {
  596. // NOTE: Since version 3.0.25, the command 'net rap server domain ...'
  597. // will through an error. We have to use 'net rap server ...'. This is
  598. // also compatible with earlier version.
  599. // This only works with the rap protocol:
  600. args.append( " rap server" );
  601. break;
  602. }
  603. case LookupHost:
  604. {
  605. // Check that the server name is present:
  606. if ( networkItem.stripWhiteSpace().isEmpty() )
  607. {
  608. Smb4KError::error( ERROR_NET_COMMAND, args.stripWhiteSpace() );
  609. return args; // still empty
  610. }
  611. // This lookup command takes no protocol:
  612. args.append( TQString( " lookup host %1" ).tqarg( networkItem ) );
  613. break;
  614. }
  615. case LookupMaster:
  616. {
  617. // Check that the domain name is present:
  618. if ( networkItem.stripWhiteSpace().isEmpty() )
  619. {
  620. Smb4KError::error( ERROR_NET_COMMAND, args.stripWhiteSpace() );
  621. return args; // still empty
  622. }
  623. // This lookup command takes no protocol:
  624. args.append( TQString( " lookup master '%1'" ).tqarg( networkItem ) );
  625. break;
  626. }
  627. case Domain:
  628. {
  629. // This only works with the rap protocol:
  630. args.append( " rap domain" );
  631. break;
  632. }
  633. default:
  634. {
  635. // Bypass the rest and return an
  636. // empty string:
  637. return args;
  638. }
  639. }
  640. args.append( !domain.isEmpty() ?
  641. TQString( " -W '%1'" ).tqarg( domain ) :
  642. TQString() );
  643. args.append( !netbios_name.isEmpty() ?
  644. TQString( " -n '%1'" ).tqarg( netbios_name ) :
  645. TQString() );
  646. args.append( Smb4KSettings::machineAccount() ?
  647. " -P" :
  648. TQString() );
  649. args.append( TQString( " -p %1" ).tqarg( port ) );
  650. return args;
  651. }
  652. const TQString Smb4KSambaOptionsHandler::mountOptions( const TQString &share )
  653. {
  654. Smb4KSambaOptionsInfo *info = find_item( share );
  655. TQString args;
  656. // Read the global Samba options from smb.conf:
  657. (void) globalSambaOptions();
  658. // Get the strings needed to put the argument list together:
  659. TQString uid = (info && !info->uid().isEmpty()) ?
  660. info->uid() :
  661. Smb4KSettings::userID();
  662. TQString gid = (info && !info->gid().isEmpty()) ?
  663. info->gid() :
  664. Smb4KSettings::groupID();
  665. TQString charset, codepage;
  666. switch ( Smb4KSettings::clientCharset() )
  667. {
  668. case Smb4KSettings::EnumClientCharset::default_charset:
  669. {
  670. charset = m_samba_options["unix charset"].lower(); // maybe empty
  671. break;
  672. }
  673. case Smb4KSettings::EnumClientCharset::iso8859_1:
  674. {
  675. charset = "iso8859-1";
  676. break;
  677. }
  678. case Smb4KSettings::EnumClientCharset::iso8859_2:
  679. {
  680. charset = "iso8859-2";
  681. break;
  682. }
  683. case Smb4KSettings::EnumClientCharset::iso8859_3:
  684. {
  685. charset = "iso8859-3";
  686. break;
  687. }
  688. case Smb4KSettings::EnumClientCharset::iso8859_4:
  689. {
  690. charset = "iso8859-4";
  691. break;
  692. }
  693. case Smb4KSettings::EnumClientCharset::iso8859_5:
  694. {
  695. charset = "iso8859-5";
  696. break;
  697. }
  698. case Smb4KSettings::EnumClientCharset::iso8859_6:
  699. {
  700. charset = "iso8859-6";
  701. break;
  702. }
  703. case Smb4KSettings::EnumClientCharset::iso8859_7:
  704. {
  705. charset = "iso8859-7";
  706. break;
  707. }
  708. case Smb4KSettings::EnumClientCharset::iso8859_8:
  709. {
  710. charset = "iso8859-8";
  711. break;
  712. }
  713. case Smb4KSettings::EnumClientCharset::iso8859_9:
  714. {
  715. charset = "iso8859-9";
  716. break;
  717. }
  718. case Smb4KSettings::EnumClientCharset::iso8859_13:
  719. {
  720. charset = "iso8859-13";
  721. break;
  722. }
  723. case Smb4KSettings::EnumClientCharset::iso8859_14:
  724. {
  725. charset = "iso8859-14";
  726. break;
  727. }
  728. case Smb4KSettings::EnumClientCharset::iso8859_15:
  729. {
  730. charset = "iso8859-15";
  731. break;
  732. }
  733. case Smb4KSettings::EnumClientCharset::utf8:
  734. {
  735. charset = "utf8";
  736. break;
  737. }
  738. case Smb4KSettings::EnumClientCharset::koi8_r:
  739. {
  740. charset = "koi8-r";
  741. break;
  742. }
  743. case Smb4KSettings::EnumClientCharset::koi8_u:
  744. {
  745. charset = "koi8-u";
  746. break;
  747. }
  748. case Smb4KSettings::EnumClientCharset::koi8_ru:
  749. {
  750. charset = "koi8-ru";
  751. break;
  752. }
  753. case Smb4KSettings::EnumClientCharset::cp1251:
  754. {
  755. charset = "cp1251";
  756. break;
  757. }
  758. case Smb4KSettings::EnumClientCharset::gb2312:
  759. {
  760. charset = "gb2312";
  761. break;
  762. }
  763. case Smb4KSettings::EnumClientCharset::big5:
  764. {
  765. charset = "big5";
  766. break;
  767. }
  768. case Smb4KSettings::EnumClientCharset::euc_jp:
  769. {
  770. charset = "euc-jp";
  771. break;
  772. }
  773. case Smb4KSettings::EnumClientCharset::euc_kr:
  774. {
  775. charset = "euc-kr";
  776. break;
  777. }
  778. case Smb4KSettings::EnumClientCharset::tis_620:
  779. {
  780. charset = "tis-620";
  781. break;
  782. }
  783. default:
  784. {
  785. break;
  786. }
  787. }
  788. switch ( Smb4KSettings::serverCodepage() )
  789. {
  790. case Smb4KSettings::EnumServerCodepage::default_codepage:
  791. {
  792. codepage = m_samba_options["dos charset"].lower(); // maybe empty
  793. break;
  794. }
  795. case Smb4KSettings::EnumServerCodepage::cp437:
  796. {
  797. codepage = "cp437";
  798. break;
  799. }
  800. case Smb4KSettings::EnumServerCodepage::cp720:
  801. {
  802. codepage = "cp720";
  803. break;
  804. }
  805. case Smb4KSettings::EnumServerCodepage::cp737:
  806. {
  807. codepage = "cp737";
  808. break;
  809. }
  810. case Smb4KSettings::EnumServerCodepage::cp775:
  811. {
  812. codepage = "cp775";
  813. break;
  814. }
  815. case Smb4KSettings::EnumServerCodepage::cp850:
  816. {
  817. codepage = "cp850";
  818. break;
  819. }
  820. case Smb4KSettings::EnumServerCodepage::cp852:
  821. {
  822. codepage = "cp852";
  823. break;
  824. }
  825. case Smb4KSettings::EnumServerCodepage::cp855:
  826. {
  827. codepage = "cp855";
  828. break;
  829. }
  830. case Smb4KSettings::EnumServerCodepage::cp857:
  831. {
  832. codepage = "cp857";
  833. break;
  834. }
  835. case Smb4KSettings::EnumServerCodepage::cp858:
  836. {
  837. codepage = "cp858";
  838. break;
  839. }
  840. case Smb4KSettings::EnumServerCodepage::cp860:
  841. {
  842. codepage = "cp860";
  843. break;
  844. }
  845. case Smb4KSettings::EnumServerCodepage::cp861:
  846. {
  847. codepage = "cp861";
  848. break;
  849. }
  850. case Smb4KSettings::EnumServerCodepage::cp862:
  851. {
  852. codepage = "cp862";
  853. break;
  854. }
  855. case Smb4KSettings::EnumServerCodepage::cp863:
  856. {
  857. codepage = "cp863";
  858. break;
  859. }
  860. case Smb4KSettings::EnumServerCodepage::cp864:
  861. {
  862. codepage = "cp864";
  863. break;
  864. }
  865. case Smb4KSettings::EnumServerCodepage::cp865:
  866. {
  867. codepage = "cp865";
  868. break;
  869. }
  870. case Smb4KSettings::EnumServerCodepage::cp866:
  871. {
  872. codepage = "cp866";
  873. break;
  874. }
  875. case Smb4KSettings::EnumServerCodepage::cp869:
  876. {
  877. codepage = "cp869";
  878. break;
  879. }
  880. case Smb4KSettings::EnumServerCodepage::cp874:
  881. {
  882. codepage = "cp874";
  883. break;
  884. }
  885. case Smb4KSettings::EnumServerCodepage::cp932:
  886. {
  887. codepage = "cp932";
  888. break;
  889. }
  890. case Smb4KSettings::EnumServerCodepage::cp936:
  891. {
  892. codepage = "cp936";
  893. break;
  894. }
  895. case Smb4KSettings::EnumServerCodepage::cp949:
  896. {
  897. codepage = "cp949";
  898. break;
  899. }
  900. case Smb4KSettings::EnumServerCodepage::cp950:
  901. {
  902. codepage = "cp950";
  903. break;
  904. }
  905. case Smb4KSettings::EnumServerCodepage::cp1250:
  906. {
  907. codepage = "cp1250";
  908. break;
  909. }
  910. case Smb4KSettings::EnumServerCodepage::cp1251:
  911. {
  912. codepage = "cp1251";
  913. break;
  914. }
  915. case Smb4KSettings::EnumServerCodepage::cp1252:
  916. {
  917. codepage = "cp1252";
  918. break;
  919. }
  920. case Smb4KSettings::EnumServerCodepage::cp1253:
  921. {
  922. codepage = "cp1253";
  923. break;
  924. }
  925. case Smb4KSettings::EnumServerCodepage::cp1254:
  926. {
  927. codepage = "cp1254";
  928. break;
  929. }
  930. case Smb4KSettings::EnumServerCodepage::cp1255:
  931. {
  932. codepage = "cp1255";
  933. break;
  934. }
  935. case Smb4KSettings::EnumServerCodepage::cp1256:
  936. {
  937. codepage = "cp1256";
  938. break;
  939. }
  940. case Smb4KSettings::EnumServerCodepage::cp1257:
  941. {
  942. codepage = "cp1257";
  943. break;
  944. }
  945. case Smb4KSettings::EnumServerCodepage::cp1258:
  946. {
  947. codepage = "cp1258";
  948. break;
  949. }
  950. case Smb4KSettings::EnumServerCodepage::unicode:
  951. {
  952. codepage = "tqunicode";
  953. break;
  954. }
  955. default:
  956. {
  957. break;
  958. }
  959. }
  960. #ifndef __FreeBSD__
  961. TQString netbios_name = !Smb4KSettings::netBIOSName().isEmpty() ?
  962. Smb4KSettings::netBIOSName() :
  963. m_samba_options["netbios name"];
  964. TQString socket_options = (!Smb4KSettings::socketOptions().isEmpty() &&
  965. TQString::compare( Smb4KSettings::socketOptions(),
  966. m_samba_options["socket options"] ) != 0) ?
  967. Smb4KSettings::socketOptions() :
  968. TQString();
  969. TQString netbios_scope = (!Smb4KSettings::netBIOSScope().isEmpty() &&
  970. TQString::compare( Smb4KSettings::netBIOSScope(),
  971. m_samba_options["netbios scope"] ) != 0) ?
  972. Smb4KSettings::netBIOSScope() :
  973. TQString();
  974. int port = info && info->port() != -1 ?
  975. info->port() :
  976. Smb4KSettings::remotePort();
  977. bool kerberos = info ?
  978. info->kerberos() :
  979. Smb4KSettings::useKerberos();
  980. bool read_write = info ?
  981. info->writeAccess() :
  982. (Smb4KSettings::writeAccess() == Smb4KSettings::EnumWriteAccess::ReadWrite);
  983. // Compile the arguments list:
  984. args.append( !netbios_name.isEmpty() ?
  985. TQString( "netbiosname='%1'," ).tqarg( netbios_name ) :
  986. TQString() );
  987. args.append( !uid.isEmpty() ?
  988. TQString( "uid=%1," ).tqarg( uid ) :
  989. TQString() );
  990. args.append( !gid.isEmpty() ?
  991. TQString( "gid=%1," ).tqarg( gid ) :
  992. TQString() );
  993. args.append( TQString( "port=%1," ).tqarg( port ) );
  994. args.append( !charset.isEmpty() ?
  995. TQString( "iocharset=%1," ).tqarg( charset ) :
  996. TQString() );
  997. args.append( read_write ? "rw," : "ro," );
  998. switch ( Smb4KSettings::filesystem() )
  999. {
  1000. case Smb4KSettings::EnumFilesystem::CIFS:
  1001. {
  1002. args.append( !Smb4KSettings::fileMask().isEmpty() ?
  1003. TQString( "file_mode=%1," ).tqarg( Smb4KSettings::fileMask() ) :
  1004. TQString() );
  1005. args.append( !Smb4KSettings::directoryMask().isEmpty() ?
  1006. TQString( "dir_mode=%1," ).tqarg( Smb4KSettings::directoryMask() ) :
  1007. TQString() );
  1008. args.append( Smb4KSettings::permissionChecks() ?
  1009. "perm," :
  1010. "noperm," );
  1011. args.append( Smb4KSettings::clientControlsIDs() ?
  1012. "setuids," :
  1013. "nosetuids," );
  1014. args.append( Smb4KSettings::serverInodeNumbers() ?
  1015. "serverino," :
  1016. "noserverino," );
  1017. args.append( Smb4KSettings::inodeDataCaching() ?
  1018. "directio," :
  1019. TQString() ); // FIXME: Does 'nodirectio' exist?
  1020. args.append( Smb4KSettings::translateReservedChars() ?
  1021. "mapchars," :
  1022. "nomapchars," );
  1023. args.append( Smb4KSettings::noLocking() ?
  1024. "nolock," :
  1025. TQString() ); // FIXME: Does 'lock' exist?
  1026. args.append( !Smb4KSettings::customCIFSOptions().isEmpty() ?
  1027. Smb4KSettings::customCIFSOptions() :
  1028. TQString() );
  1029. break;
  1030. }
  1031. case Smb4KSettings::EnumFilesystem::SMBFS:
  1032. {
  1033. args.append( !socket_options.isEmpty() ?
  1034. TQString( "sockopt='%1'," ).tqarg( socket_options ) :
  1035. TQString() );
  1036. args.append( !netbios_scope.isEmpty() ?
  1037. TQString( "scope=%1," ).tqarg( netbios_scope ) :
  1038. TQString() );
  1039. args.append( !codepage.isEmpty() ?
  1040. TQString( "codepage=%1," ).tqarg( codepage ) :
  1041. TQString() );
  1042. args.append( !Smb4KSettings::fileMask().isEmpty() ?
  1043. TQString( "fmask=%1," ).tqarg( Smb4KSettings::fileMask() ) :
  1044. TQString() );
  1045. args.append( !Smb4KSettings::directoryMask().isEmpty() ?
  1046. TQString( "dmask=%1," ).tqarg( Smb4KSettings::directoryMask() ) :
  1047. TQString() );
  1048. args.append( kerberos ? "krb," : TQString() );
  1049. args.append( Smb4KSettings::cachingTime() != 1000 ?
  1050. TQString( "ttl=%1," ).tqarg( Smb4KSettings::cachingTime() ) :
  1051. TQString() );
  1052. args.append( Smb4KSettings::unicodeSupport() ?
  1053. "tqunicode," :
  1054. TQString() );
  1055. args.append( Smb4KSettings::largeFileSystemSupport() ?
  1056. "lfs," :
  1057. TQString() );
  1058. break;
  1059. }
  1060. default:
  1061. {
  1062. break;
  1063. }
  1064. }
  1065. #else
  1066. // Compile the arguments list:
  1067. args.append( !uid.isEmpty() ?
  1068. TQString( " -u %1" ).tqarg( uid ) :
  1069. TQString() );
  1070. args.append( !gid.isEmpty() ?
  1071. TQString( " -g %1" ).tqarg( gid ) :
  1072. TQString() );
  1073. args.append( !charset.isEmpty() && !codepage.isEmpty() ?
  1074. TQString( " -E %1:%2" ).tqarg( charset, codepage ) :
  1075. TQString() );
  1076. args.append( !Smb4KSettings::fileMask().isEmpty() ?
  1077. TQString( " -f %1" ).tqarg( Smb4KSettings::fileMask() ) :
  1078. TQString() );
  1079. args.append( !Smb4KSettings::directoryMask().isEmpty() ?
  1080. TQString( " -d %1" ).tqarg( Smb4KSettings::directoryMask() ) :
  1081. TQString() );
  1082. // NOTE: Under FreeBSD the port must be managed by the mounter.
  1083. // FIXME: If the manual page was of more use, we could probably implement
  1084. // more of the arguments that are available for mount_smbfs.
  1085. #endif
  1086. return args;
  1087. }
  1088. void Smb4KSambaOptionsHandler::read_smb_conf()
  1089. {
  1090. // Clear the options list before reading.
  1091. m_samba_options.clear();
  1092. TQStringList paths;
  1093. paths << "/etc";
  1094. paths << "/etc/samba";
  1095. paths << "/usr/local/etc";
  1096. paths << "/usr/local/etc/samba";
  1097. TQFile f( "smb.conf" );
  1098. TQStringList contents;
  1099. // Locate the file and read its contents:
  1100. for ( TQStringList::Iterator it = paths.begin(); it != paths.end(); ++it )
  1101. {
  1102. TQDir::setCurrent( *it );
  1103. if ( f.exists() )
  1104. {
  1105. if ( f.open( IO_ReadOnly ) )
  1106. {
  1107. TQTextStream ts( &f );
  1108. ts.setEncoding( TQTextStream::Locale );
  1109. contents = TQStringList::split( '\n', ts.read(), false );
  1110. }
  1111. f.close();
  1112. break;
  1113. }
  1114. else
  1115. {
  1116. continue;
  1117. }
  1118. }
  1119. // Process the file contents.
  1120. for ( TQStringList::Iterator it = contents.erase( contents.begin(), ++(contents.find( "[global]" )) ); it != contents.end(); ++it )
  1121. {
  1122. if ( (*it).stripWhiteSpace().startsWith( "#" ) || (*it).stripWhiteSpace().startsWith( ";" ) )
  1123. {
  1124. *it = TQString();
  1125. }
  1126. else if ( (*it).stripWhiteSpace().startsWith( "include" ) )
  1127. {
  1128. // Put the contents of the included at this position.
  1129. TQString file = (*it).section( "=", 1, 1 ).stripWhiteSpace();
  1130. *it = TQString();
  1131. f.setName( file );
  1132. TQStringList include;
  1133. if ( f.exists() )
  1134. {
  1135. if ( f.open( IO_ReadOnly ) )
  1136. {
  1137. TQTextStream ts( &f );
  1138. ts.setEncoding( TQTextStream::Locale );
  1139. include = TQStringList::split( '\n', ts.read(), false );
  1140. }
  1141. f.close();
  1142. }
  1143. for ( TQStringList::Iterator i = include.begin(); i != include.end(); ++i )
  1144. {
  1145. if ( !(*i).stripWhiteSpace().isEmpty() )
  1146. {
  1147. contents.insert( it, *i );
  1148. continue;
  1149. }
  1150. else
  1151. {
  1152. continue;
  1153. }
  1154. }
  1155. continue;
  1156. }
  1157. else if ( (*it).startsWith( "[" ) )
  1158. {
  1159. contents.erase( it, contents.end() );
  1160. break;
  1161. }
  1162. else
  1163. {
  1164. continue;
  1165. }
  1166. }
  1167. contents.remove( TQString() );
  1168. // Write all options into the map:
  1169. for ( TQStringList::ConstIterator it = contents.begin(); it != contents.end(); ++it )
  1170. {
  1171. TQString key = (*it).section( "=", 0, 0 ).stripWhiteSpace().lower();
  1172. m_samba_options[key] = TQString( (*it).section( "=", 1, 1 ).stripWhiteSpace().upper() );
  1173. }
  1174. // Post-processing. Some values should be entered with their defaults, if they are
  1175. // not already present.
  1176. if ( !m_samba_options.contains( "netbios name" ) )
  1177. {
  1178. size_t hostnamelen = 255;
  1179. char *hostname = new char[hostnamelen];
  1180. if ( gethostname( hostname, hostnamelen ) == -1 )
  1181. {
  1182. int error = errno;
  1183. Smb4KError::error( ERROR_GETTING_HOSTNAME, TQString(), strerror( error ) );
  1184. }
  1185. else
  1186. {
  1187. m_samba_options["netbios name"] = ( TQString( "%1" ).tqarg( hostname ) ).upper();
  1188. }
  1189. delete [] hostname;
  1190. }
  1191. }
  1192. const TQMap<TQString,TQString> &Smb4KSambaOptionsHandler::globalSambaOptions()
  1193. {
  1194. if ( m_samba_options.isEmpty() )
  1195. {
  1196. read_smb_conf();
  1197. }
  1198. return m_samba_options;
  1199. }
  1200. const TQString &Smb4KSambaOptionsHandler::winsServer()
  1201. {
  1202. if ( m_wins_server.isEmpty() )
  1203. {
  1204. (void) globalSambaOptions();
  1205. if ( !m_samba_options["wins server"].isEmpty() )
  1206. {
  1207. m_wins_server = m_samba_options["wins server"];
  1208. }
  1209. else if ( !m_samba_options["wins support"].isEmpty() &&
  1210. (TQString::compare( m_samba_options["wins support"].lower(), "yes" ) == 0 ||
  1211. TQString::compare( m_samba_options["wins support"].lower(), "true" ) == 0) )
  1212. {
  1213. m_wins_server = "127.0.0.1";
  1214. }
  1215. }
  1216. return m_wins_server;
  1217. }
  1218. void Smb4KSambaOptionsHandler::addItem( Smb4KSambaOptionsInfo *info, bool s )
  1219. {
  1220. Smb4KSambaOptionsInfo *item = find_item( info->itemName() );
  1221. if ( item && TQString::compare( item->itemName().lower(), info->itemName().lower() ) == 0 )
  1222. {
  1223. item->setPort( info->port() );
  1224. #ifndef __FreeBSD__
  1225. item->setFilesystem( info->filesystem() );
  1226. item->setWriteAccess( info->writeAccess() );
  1227. #endif
  1228. item->setRemount( info->remount() );
  1229. item->setProtocol( info->protocol() );
  1230. item->setKerberos( info->kerberos() );
  1231. item->setUID( info->uid() );
  1232. item->setGID( info->gid() );
  1233. delete info;
  1234. }
  1235. else
  1236. {
  1237. m_list.append( info );
  1238. }
  1239. if ( s )
  1240. {
  1241. sync();
  1242. }
  1243. }
  1244. void Smb4KSambaOptionsHandler::removeItem( const TQString &name, bool s )
  1245. {
  1246. Smb4KSambaOptionsInfo *item = find_item( name );
  1247. if ( item && TQString::compare( item->itemName().lower(), name.lower() ) == 0 )
  1248. {
  1249. m_list.remove( item );
  1250. delete item;
  1251. }
  1252. if ( s )
  1253. {
  1254. sync();
  1255. }
  1256. }
  1257. #include "smb4ksambaoptionshandler.moc"