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

Comparing Syncify/Syncify.cpp (file contents):
Revision 437 by douglas, 2005-04-05T16:05:16-07:00 vs.
Revision 444 by douglas, 2005-04-16T22:45:40-07:00

# Line 5 | Line 5
5   // $Id$
6  
7   #include "Syncify.hpp"
8 + #include "SambaReader.hpp"
9  
10   #include <menes-api/exename.hpp>
11   #include <menes-app/simple.hpp>
# Line 51 | Line 52 | extern "C"
52   {
53          void authenticate(const char* srv, const char* shr, char* wg, int wglen, char* un, int unlen, char* pw, int pwlen)
54          {
55 <                static ext::String user("Douglas Thrift"), password(::getpass("Password:"));
55 >                static ext::Buffer user("Douglas Thrift"), password(::getpass("Password:"));
56  
57 <                _foreach (ext::String, atom, user)
57 >                _foreach (ext::Buffer, atom, user)
58                          un[_index] = *atom;
59 <                _foreach (ext::String, atom, password)
59 >                _foreach (ext::Buffer, atom, password)
60                          pw[_index] = *atom;
61  
62                  un[user.GetSize() < size_t(unlen) ? user.GetSize() : unlen - 1] = '\0';
# Line 63 | Line 64 | extern "C"
64          }
65   }
66  
67 < Syncify::Syncify(const ext::String& local, const ext::String& remote, const ext::String& pattern) : pattern(pattern)
67 > Syncify::Syncify(const ext::String& local, const ext::String& remote, const ext::String& pattern) : pattern(pattern), transfering(true), transferers(etl::BindAll(&Syncify::transfer, this))
68   {
69          CheckError(::smbc_init(authenticate, debug ? 2 : 0));
70  
71 +        transferers.Add(1);
72 +
73          syncify(local, remote);
74 +
75 +        transfering = false;
76   }
77  
78   Syncify::~Syncify()
79   {
80 +        transferers.Join();
81 +
82 +        api::Cout << ios::NewLine;
83 +
84          ::smbc_free_context(::smbc_set_context(NULL), 1);
85   }
86  
87   ext::String Syncify::program(api::GetExecutablePath().GetName());
88   bool Syncify::debug(false);
89  
90 < void Syncify::syncify(const ext::String& local, const ext::String& remote)
90 > void Syncify::syncify(const api::Path& local, const ext::String& remote)
91   {
92          try
93          {
# Line 91 | Line 100 | void Syncify::syncify(const ext::String&
100                  case SMBC_FILE:
101                          if (entity->name == pattern)
102                          {
103 <                                api::Cout << entity->name << ios::NewLine;
103 >                                api::Path path(local.GetChild(entity->name));
104 >
105 >                                if (!path.Exists())
106 >                                {
107 >                                        api::Cout << "+" << entity->name << ios::Flush;
108 >
109 >                                        ext::Buffer buffer(entity->name);
110 >
111 >                                        buffer.SetSize(buffer.GetSize() * 3);
112 >
113 >                                        ::smbc_urlencode(buffer.Begin(), entity->name, buffer.GetSize());
114 >
115 >                                        _synchronized (transfersLock)
116 >                                                transfers.push(Transfer(path.GetPath(), remote + "/" + ext::String(buffer)));
117 >                                }
118 >                                else
119 >                                        api::Cout << "-" << ios::Flush;
120                          }
121                          break;
122                  case SMBC_DIR:
# Line 103 | Line 128 | void Syncify::syncify(const ext::String&
128                  ::smbc_closedir(directory);
129  
130                  _foreach (const ext::RedBlackSet<ext::String>, directory, directories)
131 <                        syncify(local + "/" + *directory, remote + "/" + *directory);
131 >                        syncify(local.GetChild(*directory), remote + "/" + *directory);
132 >        }
133 >        catch (const Error& error) {}
134 > }
135 >
136 > int Syncify::transfer()
137 > {
138 >        _synchronized (transfersLock) while (transfering || !transfers.empty()) if (!transfers.empty())
139 >        {
140 >                Transfer transfer(transfers.front());
141 >
142 >                transfers.pop();
143 >
144 >                _desynchronized (transfersLock)
145 >                {
146 >                        {
147 >                                api::Path file(transfer.local);
148 >                                ext::Stack<ext::String> stack;
149 >
150 >                                for (api::Path path(file.GetParent()); !path.Exists(); path = path.GetParent())
151 >                                        stack.Push(path.GetPath());
152 >
153 >                                while (!stack.IsEmpty())
154 >                                {
155 >                                        try
156 >                                        {
157 >                                                api::Posix::CheckError(::mkdir(stack.Top().NullTerminate(), 0755));
158 >                                        }
159 >                                        catch (const api::Posix::Error&) {}
160 >
161 >                                        stack.Pop();
162 >                                }
163 >                        }
164 >
165 >                        try
166 >                        {
167 >                                SambaReader samba(transfer.remote);
168 >                                api::FileWriter file(transfer.local);
169 >
170 >                                ios::ReadToWrite(samba, file);
171 >                        }
172 >                        catch (const Error& error)
173 >                        {
174 >                                api::Cerr << error << ios::NewLine;
175 >                        }
176 >                }
177          }
178 <        catch (const Error& error)
178 >        else _desynchronized (transfersLock)
179          {
180 <                api::Cerr << error.GetMessage() << remote << ios::NewLine;
180 >                ::timespec wait = { 0, 1000000 };
181 >
182 >                ::nanosleep(&wait, NULL);
183          }
184 +
185 +        return 0;
186   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines