ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/proj/trunk/Spectre/Spectre.cpp
Revision: 228
Committed: 2003-07-30T21:14:12-07:00 (21 years, 10 months ago) by douglas
File size: 10309 byte(s)
Log Message:
Made Unmounter and made autounmount work. I like cheese.

File Contents

# User Rev Content
1 douglas 152 // Spectre Samba Mounter
2     //
3     // Douglas Thrift
4     //
5 douglas 228 // $Id: Spectre.cpp,v 1.13 2003/07/31 04:14:12 douglas Exp $
6 douglas 152
7     #include "Spectre.h"
8     #include "Maker.h"
9     #include "Mounter.h"
10 douglas 227 #include "Unmounter.h"
11 douglas 152
12 douglas 153 string program;
13     string programName = "Spectre Samba Mounter";
14 douglas 226 string programVersion = "1.0rc1";
15 douglas 153 bool debug = false;
16    
17 douglas 154 Config config;
18 douglas 153
19 douglas 176 int spectre(vector<string>& args);
20     void automake(set<string>& makes);
21     void automake(set<string>& makes, ipstream& pin);
22     void automount(set<string>& mounts);
23 douglas 227 void autounmount(set<string>& unmounts);
24 douglas 176 void configure();
25    
26 douglas 152 int main(int argc, char* argv[])
27     {
28 douglas 176 vector<string> args(argc);
29 douglas 154
30 douglas 176 for (int index = 0; index < argc; index++)
31     {
32     args[index] = argv[index];
33     }
34    
35     return spectre(args);
36     }
37    
38     int spectre(vector<string>& args)
39     {
40     program = args[0];
41    
42 douglas 154 #include "configure.h"
43 douglas 155
44     bool make = false;
45     bool mount = false;
46 douglas 227 bool unmount = false;
47 douglas 176 bool automake = false;
48     bool automount = false;
49 douglas 227 bool autounmount = false;
50 douglas 155
51     set<string> makes;
52     set<string> mounts;
53 douglas 227 set<string> unmounts;
54 douglas 153
55 douglas 176 for (int index = 1; index < args.size(); index++)
56 douglas 153 {
57 douglas 176 if (args[index] == "-help")
58 douglas 153 {
59 douglas 155 usage();
60 douglas 153 return 0;
61     }
62 douglas 176 else if (args[index] == "-version")
63 douglas 153 {
64 douglas 155 version();
65 douglas 153 return 0;
66     }
67 douglas 176 else if (args[index] == "-make")
68 douglas 153 {
69 douglas 155 if (!make) make = true;
70    
71 douglas 176 if (++index < args.size())
72 douglas 155 {
73 douglas 176 makes.insert(args[index]);
74 douglas 155 }
75     else
76     {
77     cerr << program << ": Bad arguments\n";
78     usage();
79     return 1;
80     }
81 douglas 153 }
82 douglas 176 else if (args[index] == "-mount")
83 douglas 153 {
84 douglas 155 if (!mount) mount = true;
85    
86 douglas 176 if (++index < args.size())
87 douglas 155 {
88 douglas 176 mounts.insert(args[index]);
89 douglas 155 }
90     else
91     {
92     cerr << program << ": Bad arguments\n";
93     usage();
94     return 1;
95     }
96 douglas 153 }
97 douglas 227 else if (args[index] == "-unmount")
98     {
99     if (!unmount) unmount = true;
100    
101     if (++index < args.size())
102     {
103     unmounts.insert(args[index]);
104     }
105     else
106     {
107     cerr << program << ": Bad arguments\n";
108     usage();
109     return 1;
110     }
111     }
112 douglas 176 else if (args[index] == "-automake")
113 douglas 153 {
114 douglas 176 if (!automake) automake = true;
115     }
116     else if (args[index] == "-automount")
117     {
118     if (!automount) automount = true;
119     }
120 douglas 227 else if (args[index] == "-autounmount")
121     {
122     if (!autounmount) autounmount = true;
123     }
124 douglas 176 else if (args[index] == "-D")
125     {
126 douglas 155 if (!debug)
127     {
128     debug = true;
129     cerr.setf(ios_base::boolalpha);
130     }
131 douglas 153 }
132     }
133    
134 douglas 227 if (!make && !mount && !unmount && !automake && !automount && !autounmount)
135 douglas 155 {
136     usage();
137     return 0;
138     }
139 douglas 152
140 douglas 155 if (debug)
141     {
142     cerr << "make = " << make << "\n"
143     << (make ? "makes = {\n" : "");
144    
145     for (set<string>::iterator itor = makes.begin(); itor != makes.end();
146     itor++)
147     {
148     cerr << " " << *itor << "\n";
149     }
150    
151     cerr << (make ? "}\n" : "")
152     << "mount = " << mount << "\n"
153     << (mount ? "mounts = {\n" : "");
154    
155     for (set<string>::iterator itor = mounts.begin(); itor != mounts.end();
156     itor++)
157     {
158     cerr << " " << *itor << "\n";
159     }
160    
161     cerr << (mount ? "}\n" : "")
162 douglas 227 << "unmount = " << unmount << "\n"
163     << (unmount ? "unmounts = {\n" : "");
164    
165     for (set<string>::iterator itor = unmounts.begin(); itor !=
166     unmounts.end(); itor++)
167     {
168     cerr << " " << *itor << "\n";
169     }
170    
171     cerr << (unmount ? "}\n" : "")
172 douglas 176 << "automake = " << automake << "\n"
173     << "automount = " << automount << "\n"
174 douglas 227 << "autounmount = " << autounmount << "\n"
175 douglas 155 << "config.install = " << config.install << "\n";
176     }
177    
178 douglas 159 configure();
179 douglas 155
180     if (debug)
181     {
182 douglas 176 cerr << "config.findsmb = " << config.findsmb << "\n"
183     << "config.smbclient = " << config.smbclient << "\n"
184 douglas 159 << "config.mount = " << config.mount << "\n"
185 douglas 227 << "config.umount = " << config.umount << "\n"
186 douglas 159 << "config.root = " << config.root << "\n"
187 douglas 155 << (!config.hosts.empty() ? "config.hosts = {\n" : "");
188    
189     for (multimap<string, string>::iterator itor = config.hosts.begin();
190     itor != config.hosts.end(); itor++)
191     {
192     cerr << " " << itor->first << " = " << itor->second << "\n";
193     }
194    
195     cerr << (!config.hosts.empty() ? "}\n" : "");
196     }
197    
198 douglas 176 if (automake) ::automake(makes);
199    
200     if (make || automake)
201 douglas 160 {
202     for (set<string>::iterator itor = makes.begin(); itor != makes.end();
203     itor++)
204     {
205     Maker maker(*itor);
206    
207     maker.make();
208     }
209     }
210    
211 douglas 176 if (automount) ::automount(mounts);
212    
213     if (mount || automount)
214 douglas 160 {
215     for (set<string>::iterator itor = mounts.begin(); itor != mounts.end();
216     itor++)
217     {
218     Mounter mounter(*itor);
219    
220     mounter.mount();
221     }
222     }
223    
224 douglas 227 if (autounmount) ::autounmount(unmounts);
225    
226     if (unmount || autounmount)
227     {
228     for (set<string>::iterator itor = unmounts.begin(); itor !=
229     unmounts.end(); itor++)
230     {
231     Unmounter unmounter(*itor);
232    
233     unmounter.unmount();
234     }
235     }
236    
237 douglas 152 return 0;
238     }
239 douglas 155
240     string platform()
241     {
242     utsname* computer = new utsname;
243     uname(computer);
244    
245     string os = computer->sysname;
246     string version = computer->release;
247     string architecture = computer->machine;
248    
249     delete computer;
250    
251     string platform = "(" + os + " " + version + " " + architecture + ")";
252    
253     return platform;
254     }
255    
256     void usage()
257     {
258 douglas 176 string tab(8 + program.length(), ' ');
259    
260 douglas 227 cout << "Usage: " << program << " [-make host ...] [-mount host ...] [-unm"
261     << "ount host ...]\n"
262     << tab << "[-automake] [-automount] [-autounmount]\n"
263 douglas 176 << tab << "[-D] [-version] [-help]\n"
264 douglas 155 << "Options:\n"
265     << " -make host Make the mount tree for host\n"
266     << " -mount host Mount the shares on host to its tree\n"
267 douglas 227 << " -unmount host Unmount the shares on host from its tree\n"
268 douglas 176 << " -automake Automagically make the mount tree\n"
269     << " -automount Automagically mount shares to the tree\n"
270 douglas 227 << " -autounmount Automagically unmount dead shares from the tre"
271     << "e\n"
272 douglas 155 << " -D Display debug information\n"
273     << " -version Display version information and exit\n"
274     << " -help Display this message and exit\n";
275     }
276    
277     void version()
278     {
279     cout << programName << " " << programVersion << " "<< platform() << "\n\n"
280     << " Copyright (C) 2003, Douglas Thrift. All Rights Reserved.\n\n"
281     << " This product includes software developed by Douglas Thrift\n"
282     << " (http://computers.douglasthrift.net/).\n";
283     }
284 douglas 159
285 douglas 176 void automake(set<string>& makes)
286     {
287     vector<string> args;
288    
289     args.push_back("spectre");
290    
291     ipstream findsmb(config.findsmb, args);
292    
293     if (debug) cerr << "findsmb = {\n";
294    
295 douglas 226 do
296 douglas 176 {
297 douglas 226 if (isdigit(findsmb.peek())) break;
298    
299 douglas 176 string line;
300    
301     getline(findsmb, line);
302    
303     if (debug) cerr << line << "\n";
304     }
305 douglas 226 while (findsmb.good());
306 douglas 176
307     automake(makes, findsmb);
308    
309     if (debug) cerr << "}\n";
310    
311     findsmb.close();
312    
313     if (debug)
314     {
315     cerr << "makes = {\n";
316    
317     for (set<string>::iterator itor = makes.begin(); itor != makes.end();
318     itor++)
319     {
320     cerr << " " << *itor << "\n";
321     }
322    
323     cerr << "}\n";
324     }
325     }
326    
327     void automake(set<string>& makes, ipstream& pin)
328     {
329     while (pin.good())
330     {
331     if (!isdigit(pin.peek())) break;
332    
333     char ip[17];
334 douglas 226 string tab;
335     char host[15];
336 douglas 176 string info;
337    
338     pin.get(ip, 17);
339 douglas 226
340     while (isspace(pin.peek()))
341     {
342     tab += pin.get();
343     }
344    
345     pin.get(host, 15);
346 douglas 176 getline(pin, info);
347    
348 douglas 226 if (debug) cerr << ip << tab << host << info << "\n";
349 douglas 176
350     strip(host);
351    
352     makes.insert(tolower(host));
353     }
354    
355     string line;
356    
357     getline(pin, line);
358    
359     if (debug) cerr << line << "\n";
360    
361     if (line != "")
362     {
363     cerr << program << ": Unknown error\n";
364     }
365     }
366    
367     void automount(set<string>& mounts)
368     {
369 douglas 202 vector<string> args;
370    
371     args.push_back("spectre");
372    
373     ipstream findsmb(config.findsmb, args);
374    
375     if (debug) cerr << "findsmb = {\n";
376    
377 douglas 226 do
378 douglas 202 {
379 douglas 226 if (isdigit(findsmb.peek())) break;
380    
381 douglas 202 string line;
382    
383     getline(findsmb, line);
384    
385     if (debug) cerr << line << "\n";
386     }
387 douglas 226 while (findsmb.good());
388 douglas 202
389     set<string> hosts;
390    
391     automake(hosts, findsmb);
392    
393     if (debug) cerr << "}\n";
394    
395     findsmb.close();
396    
397 douglas 177 DIR* dir = opendir(config.root.c_str());
398     dirent* file;
399    
400     while((file = readdir(dir)) != NULL)
401     {
402     struct stat dir;
403     string folder = config.root + "/" + file->d_name;
404    
405     stat(folder.c_str(), &dir);
406    
407     if (S_ISDIR(dir.st_mode))
408     {
409     string folder = file->d_name;
410    
411 douglas 202 if (folder == "." || folder == ".." || hosts.find(folder) ==
412     hosts.end()) continue;
413 douglas 177
414     mounts.insert(folder);
415     }
416     }
417    
418     closedir(dir);
419    
420     if (debug)
421     {
422     cerr << "mounts = {\n";
423    
424     for (set<string>::iterator itor = mounts.begin(); itor != mounts.end();
425     itor++)
426     {
427     cerr << " " << *itor << "\n";
428     }
429    
430     cerr << "}\n";
431     }
432 douglas 176 }
433    
434 douglas 227 void autounmount(set<string>& unmounts)
435     {
436 douglas 228 vector<string> args;
437    
438     args.push_back("spectre");
439    
440     ipstream findsmb(config.findsmb, args);
441    
442     if (debug) cerr << "findsmb = {\n";
443    
444     do
445     {
446     if (isdigit(findsmb.peek())) break;
447    
448     string line;
449    
450     getline(findsmb, line);
451    
452     if (debug) cerr << line << "\n";
453     }
454     while (findsmb.good());
455    
456     set<string> hosts;
457    
458     automake(hosts, findsmb);
459    
460     if (debug) cerr << "}\n";
461    
462     findsmb.close();
463    
464     for (multimap<string, string>::iterator itor = config.hosts.begin(); itor
465     != config.hosts.end(); itor = config.hosts.upper_bound(itor->first))
466     {
467     string host = itor->first;
468    
469     if (hosts.find(host) != hosts.end()) continue;
470    
471     unmounts.insert(host);
472     }
473    
474     if (debug)
475     {
476     cerr << "unmounts = {\n";
477    
478     for (set<string>::iterator itor = unmounts.begin(); itor !=
479     unmounts.end(); itor++)
480     {
481     cerr << " " << *itor << "\n";
482     }
483    
484     cerr << "}\n";
485     }
486 douglas 227 }
487    
488 douglas 159 void configure()
489     {
490     string conf = config.install + "/conf/spectre.conf";
491    
492     ifstream fin(conf.c_str());
493    
494     if (!fin.is_open())
495     {
496     cerr << program << ": Could not open " << conf << "\n";
497     exit(1);
498     }
499    
500     do
501     {
502 douglas 160 string line;
503    
504     getline(fin, line);
505    
506     if (line.find('#') == 0 || line == "")
507     {
508     // ignore
509     }
510 douglas 176 else if (line.find("findsmb=") == 0)
511     {
512     config.findsmb = line.substr(8);
513     }
514 douglas 160 else if (line.find("smbclient=") == 0)
515     {
516     config.smbclient = line.substr(10);
517     }
518     else if (line.find("mount=") == 0)
519     {
520     config.mount = line.substr(6);
521     }
522 douglas 228 else if (line.find("umount=") == 0)
523     {
524     config.umount = line.substr(7);
525     }
526 douglas 160 else if (line.find("root=") == 0)
527     {
528     config.root = line.substr(5);
529     }
530     else if (line.find("host=") == 0)
531     {
532     string host = line.substr(5);
533    
534     getline(fin, line);
535    
536     if (line != "{")
537     {
538     cerr << program << ": Munged configuration for " << host
539     << "\n";
540     exit(1);
541     }
542    
543     do
544     {
545     getline(fin, line);
546    
547     if (line.find("\t#") == 0)
548     {
549     // ignore
550     }
551     else if (line.find('\t') == 0)
552     {
553     config.hosts.insert(pair<string, string>(host,
554     line.substr(1)));
555     }
556     else if (line == "}")
557     {
558     break;
559     }
560     }
561     while (fin.good());
562     }
563 douglas 159 }
564     while (fin.good());
565    
566     fin.close();
567     }