ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/Spectre2/Daemon.cpp
(Generate patch)

Comparing Spectre2/Daemon.cpp (file contents):
Revision 406 by douglas, 2004-12-30T22:08:35-08:00 vs.
Revision 431 by douglas, 2005-03-26T22:35:26-08:00

# Line 5 | Line 5
5   // $Id$
6  
7   #include "Daemon.hpp"
8 + #include "Mounter.hpp"
9 + #include "Unmounter.hpp"
10  
11 < void Daemon::start()
11 > #include <menes-api/environment.hpp>
12 > #include <menes-api/socket.hpp>
13 >
14 > #include <arpa/inet.h>
15 >
16 > extern "C"
17   {
18 <        running = true;
19 <        thread = new api::Thread(etl::BindAll(&Daemon::loop, this));
18 >        void authenticate(const char* server, const char* share, char* work, int workSize, char* user, int userSize, char* password, int passwordSize);
19 > }
20 >
21 > Daemon::~Daemon()
22 > {
23 >        thread->Join();
24 >
25 >        ::smbc_free_context(::smbc_set_context(NULL), 1);
26 >
27 > #ifdef __FreeBSD__
28 >        api::Posix::CheckError(::unlink(secret.NullTerminate()));
29 > #endif
30   }
31  
32 + ext::RedBlackSet<Share> Daemon::shares;
33 + //api::ThreadMutex Daemon::smbcLock;
34 + #ifdef __FreeBSD__
35 + ext::String Daemon::secret(api::TheEnvironment.Get("HOME") + "/.nsmbrc");
36 + #endif
37 +
38   int Daemon::loop()
39   {
40 <        while (running) if (loaded) run(); else load();
40 >        while (running) if (loaded)
41 >        {
42 >                ext::ThreadSet<> threads;
43 >
44 >                threads.Add(etl::BindAll(&Daemon::work<Mounter>, this));
45 >                threads.Add(etl::BindAll(&Daemon::work<Unmounter>, this));
46 >                threads.Join();
47 >        }
48 >        else load();
49 >
50 >        return 0;
51 > }
52 >
53 > void Daemon::load()
54 > {
55 >        shares.Clear();
56 >        Share::passwords.Clear();
57 >
58 >        _H<xml::Document> document(xml::Parse(config.GetPath()));
59 >        _H<xml::Node> spectre(*document/"spectre");
60 >                
61 >        if (!(*spectre/"prefix").IsEmpty())
62 >                Spectre2::prefix = *spectre/"prefix";
63 >
64 >        if (!(*spectre/"root").IsEmpty())
65 >                Spectre2::root = *spectre/"root";
66 >
67 >        if (!(*spectre/"mount").IsEmpty())
68 >                Spectre2::mount = *spectre/"mount";
69 >
70 >        if (!(*spectre/"interval").IsEmpty())
71 >                interval = lexical_cast<unsigned>(ext::String(*spectre/"interval"));
72 >
73 >        CheckError(::smbc_init(authenticate, Spectre2::debug ? 2 : 0));
74 >
75 > #ifdef __FreeBSD__
76 >        SecretFileWriter out(secret);
77 >        ios::FormatWriter fout(out);
78 > #endif
79 >
80 >        _foreach (const xml::NodeSet, host_, *spectre/"host")
81 >        {
82 >                ext::String host(**host_/"name");
83 >
84 >                _foreach (const xml::NodeSet, share, **host_/"share")
85 >                {
86 >                        ext::String name(**share/"name"), owner(**share/"owner"), user(**share/"user"), group(**share/"group");
87 >
88 >                        shares.Insert(Share(host, name, owner, user, group));
89 >                }
90 >
91 > #ifdef __FreeBSD__
92 >                ::addrinfo* info;
93 >
94 >                api::Posix::CheckGaiError(::getaddrinfo(host.NullTerminate(), NULL, NULL, &info));
95 >
96 >                ::sockaddr_in& sock(*reinterpret_cast< ::sockaddr_in*>(info->ai_addr));
97 >                ext::Buffer buffer(128);
98 >
99 >                fout << "[" << host << "]" << ios::NewLine << "addr=" << ::inet_ntop(sock.sin_family, &sock.sin_addr, buffer.Begin(), buffer.GetSize()) << ios::NewLine;
100 >
101 >                ::freeaddrinfo(info);
102 > #endif
103 >        }
104 >
105 >        if (Spectre2::debug)
106 >                shares.Output(api::Cout);
107 >        
108 >        loaded = true;
109 > }
110 >
111 > template <typename Worker>
112 > int Daemon::work()
113 > {
114 >        while (running && loaded)
115 >        {
116 >                ext::ThreadSet<> workers;
117 >
118 >                _foreach (const ext::RedBlackSet<Share>, share, shares)
119 >                        workers.Add(etl::BindAll(&Daemon::work_<Worker>, this, *share));
120 >
121 >                // XXX: not useful for solving the problem it was supposed to solve
122 >                /*_synchronized (smbcLock) if (++count % 8 == 0) try
123 >                {
124 >                        ::SMBCCTX* context(::smbc_new_context());
125 >
126 >                        context->debug = Spectre2::debug ? 2 : 0;
127 >                        context->callbacks.auth_fn = authenticate;
128 >
129 >                        CheckError(::smbc_init_context(context));
130 >
131 >                        ::SMBCCTX* old(::smbc_set_context(context));
132 >
133 >                        CheckError(::smbc_free_context(old, 0));
134 >                }
135 >                catch (const Error&) { --count; }*/
136 >
137 >                if (running && loaded) try
138 >                {
139 >                        sleep();
140 >                }
141 >                catch (const api::Error&)
142 >                {
143 >                        api::Cout << "Can't sleep!" << ios::NewLine;
144 >                }
145 >
146 >                workers.Join();
147 >        }
148 >
149 >        return 0;
150 > }
151 >
152 > template <typename Worker>
153 > int Daemon::work_(const Share& share)
154 > {
155 >        Worker worker(share);
156 >
157 >        if (worker)
158 >                worker();
159  
160          return 0;
161   }
162 +
163 + void Daemon::sleep()
164 + {
165 +        ::timespec wait = { interval, 0 };
166 +
167 +        api::Posix::CheckError(::nanosleep(&wait, NULL));
168 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines