/libs/perl/Choicetool/RC/RCFile.pm

# · Perl · 369 lines · 241 code · 95 blank · 33 comment · 25 complexity · 6bd9e52ae70108aed2d619a91a00b337 MD5 · raw file

  1. # -*- perl -*-
  2. #
  3. # RCFile.pm
  4. #
  5. # Copyright (C) 2008, 2009 Francesco Salvestrini
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License along
  18. # with this program; if not, write to the Free Software Foundation, Inc.,
  19. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. #
  21. package Choicetool::RC::RCFile;
  22. use 5.8.0;
  23. use warnings;
  24. use strict;
  25. use diagnostics;
  26. use Choicetool::Autoconfig;
  27. use Choicetool::Base::Debug;
  28. use Choicetool::Base::Trace;
  29. use Choicetool::OS::File;
  30. sub new ($$)
  31. {
  32. my $class = shift;
  33. my $filename = shift;
  34. assert(defined($class));
  35. assert(defined($filename));
  36. my $self = { };
  37. $self->{FILENAME} = $filename;
  38. $self->{HOSTS} = { };
  39. bless $self, $class;
  40. return $self;
  41. }
  42. #
  43. # XXX FIXME: This sub is only a sketch, we should output more clearer messages
  44. #
  45. sub iscorrect ($)
  46. {
  47. my $self = shift;
  48. assert(defined($self));
  49. my $found_host = 0;
  50. for my $host (keys(%{$self->{HOSTS}})) {
  51. $found_host = 1;
  52. my $found_login = 0;
  53. for my $login (keys(%{$self->{HOSTS}->{$host}->{LOGIN}})) {
  54. $found_login = 1;
  55. if (!defined(($self->{HOSTS}->{$host}->{LOGIN}->{$login}))) {
  56. warning("Host " .
  57. "\`" . $host . "', " .
  58. "login " .
  59. "\`" . $login . "' " .
  60. "is without a password");
  61. return 1;
  62. }
  63. }
  64. if (!$found_login) {
  65. warning("Host \`" . $host . "' is without a login");
  66. return 1;
  67. }
  68. }
  69. if (!$found_host) {
  70. warning("No hosts defined");
  71. return 1;
  72. }
  73. return 1;
  74. }
  75. sub load ($)
  76. {
  77. my $self = shift;
  78. assert(defined($self));
  79. debug("Loading RC file");
  80. my $filename;
  81. $filename = $self->{FILENAME};
  82. assert(defined($filename));
  83. if (!file_ispresent($filename)) {
  84. error("File \`" . $filename . "' is not present");
  85. return 0;
  86. }
  87. my $filehandle;
  88. if (!open($filehandle, "<", $filename)) {
  89. error("Cannot open \`$filename' for input");
  90. return 0;
  91. }
  92. my $string;
  93. my $lineno;
  94. my $nodes;
  95. my $host;
  96. my $login;
  97. my $password;
  98. $host = undef;
  99. $login = undef;
  100. $password = undef;
  101. $lineno = 0;
  102. $nodes = 0;
  103. debug("Parsing file \`" . $filename . "'");
  104. while (<$filehandle>) {
  105. $string = $_;
  106. if ($string =~ /^[ \t]*\#.*$/) {
  107. # Skip comments
  108. } elsif ($string =~ /^[ \t]*$/) {
  109. # Skip empty lines
  110. } elsif ($string =~ /^[ \t]*host[ \t]+(.*)$/) {
  111. $host = $1;
  112. $login = undef;
  113. $password = undef;
  114. debug("Got $1");
  115. assert(defined($host));
  116. debug("Got host keyword at line " . $lineno . ", " .
  117. "host = \`" . $host . "'");
  118. $self->{HOSTS}->{$host} = { };
  119. $nodes++;
  120. } elsif ($string =~ /^[ \t]*login[ \t]+(.*)$/) {
  121. debug("Got $1");
  122. $login = $1;
  123. $password = undef;
  124. assert(defined($login));
  125. debug("Got login keyword at line " . $lineno . ", " .
  126. "login = \`" . $login . "'");
  127. if (!defined($host)) {
  128. error("Wrong formatted input file \`" . $filename . "'");
  129. return 0;
  130. }
  131. #if (defined($self->{HOSTS}->{$host}->{LOGIN}->{$login})) {
  132. # error("Login \`" . $login . "' already defined");
  133. # return 0;
  134. #}
  135. $self->{HOSTS}->{$host}->{LOGIN}->{$login} = undef;
  136. $nodes++;
  137. } elsif ($string =~ /^[ \t]*password[ \t]+(.*)$/) {
  138. debug("Got $1");
  139. $password = $1;
  140. assert(defined($password));
  141. debug("Got password keyword at line " . $lineno . ", " .
  142. "password = \`" . $password . "'");
  143. if (!defined($host)) {
  144. error("Wrong formatted input file \`" . $filename . "'");
  145. return 0;
  146. }
  147. if (!defined($login)) {
  148. error("Wrong formatted input file \`" . $filename . "'");
  149. return 0;
  150. }
  151. #if (defined($self->{HOSTS}->{$host}->{LOGIN}->{$login})) {
  152. # error("Login \`" . $login . "' already defined");
  153. # return 0;
  154. #}
  155. $self->{HOSTS}->{$host}->{LOGIN}->{$login} = $password;
  156. $nodes++;
  157. } else {
  158. error("Unknown input line " . $lineno . " in file " .
  159. "\`" . $filename . "'");
  160. return 0;
  161. }
  162. $lineno++;
  163. }
  164. debug("Parsing of \`" . $filename . "' complete");
  165. close($filehandle);
  166. if (!$self->iscorrect()) {
  167. error("File \`" . $filename . "' has an incorrect format");
  168. return 0;
  169. }
  170. debug("Loaded " . $nodes . " nodes");
  171. return 1;
  172. }
  173. sub save ($)
  174. {
  175. my $self = shift;
  176. assert(defined($self));
  177. debug("Saving RC file");
  178. if (!$self->iscorrect()) {
  179. error("RC Data contains incorrect data");
  180. return 0;
  181. }
  182. my $filename;
  183. $filename = $self->{FILENAME};
  184. assert(defined($filename));
  185. my $filehandle;
  186. if (!open($filehandle, ">", $filename)) {
  187. error("Cannot open \`$filename' for input");
  188. return 0;
  189. }
  190. my $nodes;
  191. $nodes = 0;
  192. for my $host (keys(%{$self->{HOSTS}})) {
  193. debug("Saving host \`" . $host . "'");
  194. print $filehandle "host " . $host . "\n";
  195. $nodes++;
  196. for my $login (keys(%{$self->{HOSTS}->{$host}->{LOGIN}})) {
  197. debug("Saving login \`" . $login . "'");
  198. print $filehandle "login " . $login . "\n";
  199. $nodes++;
  200. my $password;
  201. $password = $self->{HOSTS}->{$host}->{LOGIN}->{$login};
  202. if (defined($password)) {
  203. debug("Saving password \`" . $password . "'");
  204. print $filehandle "password " . $password . "\n";
  205. $nodes++;
  206. }
  207. }
  208. print $filehandle "\n";
  209. }
  210. debug("Saved " . $nodes . " nodes");
  211. close($filehandle);
  212. return 1;
  213. }
  214. sub add ($$$$)
  215. {
  216. my $self = shift;
  217. my $host = shift;
  218. my $login = shift;
  219. my $password = shift;
  220. assert(defined($self));
  221. assert(defined($host));
  222. assert(defined($login));
  223. assert(defined($password));
  224. debug("Adding RC entry " .
  225. "(\`" . $host . "', \`" . $login . "', \`" . $password . "')");
  226. if (!defined($self->{HOSTS})) {
  227. $self->{HOSTS} = { };
  228. debug("HOSTS created")
  229. }
  230. if (!defined($self->{HOSTS}->{$host})) {
  231. $self->{HOSTS}->{$host} = { };
  232. debug("HOSTS \`" . $host . "' created")
  233. }
  234. if (!defined($self->{HOSTS}->{$host}->{LOGIN})) {
  235. $self->{HOSTS}->{$host}->{LOGIN} = { };
  236. debug("HOSTS \`" . $host . "' LOGIN created")
  237. }
  238. $self->{HOSTS}->{$host}->{LOGIN}->{$login} = $password;
  239. debug("HOSTS \`" . $host . "' LOGIN \`" . $login . "' password created " .
  240. " with value \`" . $self->{HOSTS}->{$host}->{LOGIN}->{$login} . "'");
  241. return 1;
  242. }
  243. sub remove ($$$)
  244. {
  245. my $self = shift;
  246. my $host = shift;
  247. my $login = shift;
  248. assert(defined($self));
  249. assert(defined($host));
  250. assert(defined($login));
  251. debug("Removing RC entry " .
  252. "(\`" . $host . "', \`" . $login . "')");
  253. delete $self->{HOSTS}->{$host}->{LOGIN}->{$login};
  254. return 1;
  255. }
  256. sub foreach ($$)
  257. {
  258. my $self = shift;
  259. my $callback = shift;
  260. assert(defined($self));
  261. assert(defined($callback));
  262. for my $host (keys(%{$self->{HOSTS}})) {
  263. debug("Iterating over host \`" . $host . "'");
  264. for my $login (keys(%{$self->{HOSTS}->{$host}->{LOGIN}})) {
  265. debug("Iterating over login \`" . $login . "'");
  266. my $password;
  267. $password = $self->{HOSTS}->{$host}->{LOGIN}->{$login};
  268. if (!$callback->($host, $login, $password)) {
  269. return;
  270. }
  271. }
  272. }
  273. }
  274. 1;