main.pm 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824
  1. package eyelib::main;
  2. #
  3. # Copyright (C) Roman Dmitriev, rnd@rajven.ru
  4. #
  5. use utf8;
  6. use open ":encoding(utf8)";
  7. use Encode;
  8. use strict;
  9. use English;
  10. use FindBin '$Bin';
  11. use lib "/opt/Eye/scripts";
  12. use base 'Exporter';
  13. use vars qw(@EXPORT @ISA);
  14. use eyelib::config;
  15. use eyelib::logconfig;
  16. use Socket;
  17. use POSIX;
  18. use IO::Select;
  19. use IO::Handle;
  20. use Crypt::CBC;
  21. use MIME::Base64;
  22. our @ISA = qw(Exporter);
  23. our @EXPORT = qw(
  24. get_first_line
  25. isNotifyCreate
  26. isNotifyUpdate
  27. isNotifyDelete
  28. isNotifyNone
  29. hasNotifyFlag
  30. write_to_file
  31. in_array
  32. timestamp
  33. do_exec
  34. do_exec_ref
  35. do_exit
  36. hash_to_kv_csv
  37. sendEmail
  38. IsNotRun
  39. IsMyPID
  40. Add_PID
  41. Remove_PID
  42. IsNotLocked
  43. IsMyLock
  44. Add_Lock
  45. Remove_Lock
  46. DefHash
  47. read_file
  48. uniq
  49. strim
  50. trim
  51. hash_to_text
  52. is_integer
  53. is_float
  54. run_in_parallel
  55. translit
  56. crypt_string
  57. decrypt_string
  58. netdev_set_auth
  59. GetNowTime
  60. GetUnixTimeByStr
  61. GetTimeStrByUnixTime
  62. );
  63. BEGIN
  64. {
  65. #---------------------------------------------------------------------------------------------------------------
  66. sub get_first_line {
  67. my $msg = shift;
  68. if (!$msg) { return; }
  69. if ($msg=~ /(.*)(\n|\<br\>)/) {
  70. $msg = $1 if ($1);
  71. chomp($msg);
  72. }
  73. return $msg;
  74. }
  75. #---------------------------------------------------------------------------------------------------------
  76. # Проверяет, установлен ли флаг создания
  77. sub isNotifyCreate {
  78. my ($flags) = @_;
  79. return ($flags & NOTIFY_CREATE) == NOTIFY_CREATE;
  80. }
  81. #---------------------------------------------------------------------------------------------------------
  82. # Проверяет, установлен ли флаг изменения
  83. sub isNotifyUpdate {
  84. my ($flags) = @_;
  85. return ($flags & NOTIFY_UPDATE) == NOTIFY_UPDATE;
  86. }
  87. #---------------------------------------------------------------------------------------------------------
  88. # Проверяет, установлен ли флаг удаления
  89. sub isNotifyDelete {
  90. my ($flags) = @_;
  91. return ($flags & NOTIFY_DELETE) == NOTIFY_DELETE;
  92. }
  93. #---------------------------------------------------------------------------------------------------------
  94. # Проверяет, отключены ли все уведомления
  95. sub isNotifyNone {
  96. my ($flags) = @_;
  97. return $flags == NOTIFY_NONE;
  98. }
  99. #---------------------------------------------------------------------------------------------------------
  100. # Проверяет, установлен ли конкретный флаг
  101. sub hasNotifyFlag {
  102. my ($flags, $flagToCheck) = @_;
  103. return ($flags & $flagToCheck) == $flagToCheck;
  104. }
  105. #---------------------------------------------------------------------------------------------------------
  106. sub write_to_file {
  107. return if (!$_[0]);
  108. return if (!$_[1]);
  109. my $f_name = shift;
  110. my $cmd = shift;
  111. my $append = shift;
  112. if ($append) {
  113. open (LG,">>$f_name") || die("Error open file $f_name!!! die...");
  114. } else {
  115. open (LG,">$f_name") || die("Error open file $f_name!!! die...");
  116. }
  117. binmode(LG,':utf8');
  118. if (ref($cmd) eq 'ARRAY') {
  119. foreach my $row (@$cmd) {
  120. next if (!$row);
  121. print LG $row."\n";
  122. }
  123. } else {
  124. my @msg = split("\n",$cmd);
  125. foreach my $row (@msg) {
  126. next if (!$row);
  127. print LG $row."\n";
  128. }
  129. }
  130. close (LG);
  131. }
  132. #---------------------------------------------------------------------------------------------------------
  133. sub timestamp {
  134. my $worktime = time()-$BASETIME;
  135. #print "TimeStamp: $worktime sec.\n";
  136. log_info("TimeStamp: $worktime sec.");
  137. }
  138. #---------------------------------------------------------------------------------------------------------
  139. sub in_array {
  140. my $arr = shift;
  141. my @tmp = ();
  142. if (ref($arr)=~'ARRAY') { @tmp = @{$arr}; } else { push(@tmp,$arr); }
  143. my $value = shift;
  144. my %num = map { $_, 1 } @tmp;
  145. return $num{$value} || 0;
  146. }
  147. #---------------------------------------------------------------------------------------------------------.
  148. sub hash_to_kv_csv {
  149. my ($hash_ref, $delimiter) = @_;
  150. $delimiter ||= ',';
  151. return '' unless $hash_ref && %$hash_ref;
  152. # Экранируем специальные символы
  153. my $escape = sub {
  154. my $value = shift;
  155. return '' unless defined $value;
  156. # Если значение содержит кавычки или запятые - заключаем в кавычки
  157. if ($value =~ /["$delimiter]/) {
  158. $value =~ s/"/""/g;
  159. return '"' . $value . '"';
  160. }
  161. return $value;
  162. };
  163. # Формируем пары ключ=>значение
  164. my @pairs;
  165. while (my ($key, $value) = each %$hash_ref) {
  166. push @pairs, $escape->($key) . '=>' . $escape->($value);
  167. }
  168. return join($delimiter, sort @pairs);
  169. }
  170. #---------------------------------------------------------------------------------------------------------.
  171. sub do_exec_ref {
  172. my $ret = `$_[0] 2>&1`;
  173. my $res = $?;
  174. my %result;
  175. chomp($ret);
  176. $result{output}=$ret;
  177. $result{status}=$res;
  178. log_debug("Run: $_[0] Output:\n$ret\nResult code: $res");
  179. if ($res eq "0") { log_info("Run: $_[0] - $ret"); } else { log_error("Run: $_[0] - $ret"); }
  180. return %result;
  181. }
  182. #---------------------------------------------------------------------------------------------------------
  183. sub do_exec {
  184. my $ret = `$_[0]`;
  185. my $res = $?;
  186. log_debug("Run: $_[0] Output:\n$ret\nResult code: $res");
  187. if ($res eq "0") {
  188. log_info("Run: $_[0] - $ret");
  189. } else {
  190. $ret = "Error";
  191. log_error("Run: $_[0] - $ret");
  192. }
  193. return $ret;
  194. }
  195. #---------------------------------------------------------------------------------------------------------
  196. sub do_exit {
  197. my $worktime = time()-$BASETIME;
  198. my $code;
  199. if ($_[0]) { $code = $_[0]; } else { $code = 0; }
  200. log_info("Script work $worktime sec. Exit code: $code");
  201. exit $code;
  202. }
  203. #---------------------------------------------------------------------------------------------------------
  204. sub encode_mime_header {
  205. my ($str) = @_;
  206. return $str if $str =~ /^[[:ascii:]]*$/;
  207. my $b64 = encode_base64($str, '');
  208. $b64 =~ s/\s+$//;
  209. return "=?UTF-8?B?$b64?=";
  210. }
  211. #---------------------------------------------------------------------------------------------------------
  212. sub sendEmail {
  213. my ($subject, $msg, $use_br) = @_;
  214. return unless defined $msg && length $msg;
  215. return unless $send_email;
  216. unless (defined $sender_email && defined $admin_email) {
  217. log_error("Email addresses not defined");
  218. return;
  219. }
  220. # Санитизация (оставляет Unicode буквы/цифры)
  221. $subject =~ s/[^\p{L}\p{N}\s\-\.\,\!\?]//g;
  222. $msg =~ s/\r//g;
  223. my $html_message = <<"END_HTML";
  224. <!DOCTYPE html>
  225. <html xmlns="http://www.w3.org/1999/xhtml">
  226. <head>
  227. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  228. <title>$subject</title>
  229. </head>
  230. <body>
  231. <div>
  232. END_HTML
  233. my @lines = split(/\n/, $msg);
  234. foreach my $line (@lines) {
  235. $line = htmlspecialchars($line);
  236. $html_message .= $use_br ? "$line<br>\n" : "$line\n";
  237. }
  238. $html_message .= "</div>\n</body>\n</html>\n";
  239. # Кодируем Unicode-строку в байты UTF-8, затем в base64
  240. my $html_utf8_bytes = encode('UTF-8', $html_message);
  241. my $encoded_html = encode_base64($html_utf8_bytes);
  242. my $boundary = '----=' . time() . int(rand(1000));
  243. my $encoded_subject = encode_mime_header($subject);
  244. my $headers = <<"END_HEADERS";
  245. From: $sender_email
  246. To: $admin_email
  247. Subject: $encoded_subject
  248. MIME-Version: 1.0
  249. Content-Type: multipart/mixed; boundary="$boundary"
  250. END_HEADERS
  251. my $mime_message = <<"END_MIME";
  252. --$boundary
  253. Content-Type: text/html; charset=utf-8
  254. Content-Transfer-Encoding: base64
  255. $encoded_html
  256. --$boundary--
  257. END_MIME
  258. my $sendmail = '/usr/sbin/sendmail';
  259. unless (-x $sendmail) {
  260. log_error("Sendmail not found or not executable at $sendmail");
  261. return;
  262. }
  263. unless (open(MAIL, "|$sendmail -oi -t")) {
  264. log_error("Failed to open sendmail: $!");
  265. return;
  266. }
  267. print MAIL $headers;
  268. print MAIL $mime_message;
  269. close(MAIL) or log_error("Failed to send email: $!");
  270. log_info("Sent email from $sender_email to $admin_email with subject: $subject");
  271. log_debug("Email body:\n$msg");
  272. }
  273. #---------------------------------------------------------------------------------------------------------
  274. sub hash_to_text {
  275. my ($hash_ref, $indent, $seen) = @_;
  276. $indent ||= 0;
  277. $seen ||= {};
  278. return 'undef' unless defined $hash_ref;
  279. if (ref $hash_ref eq 'HASH') {
  280. # Защита от циклических ссылок
  281. my $addr = refaddr($hash_ref);
  282. if ($seen->{$addr}) {
  283. return '';
  284. }
  285. $seen->{$addr} = 1;
  286. my $spaces = ' ' x $indent;
  287. my @lines;
  288. for my $key (sort keys %$hash_ref) {
  289. my $value = $hash_ref->{$key};
  290. my $formatted_key = $key =~ /^[a-zA-Z_]\w*$/ ? $key : "'$key'";
  291. my $formatted_value;
  292. if (ref $value eq 'HASH') {
  293. $formatted_value = ":\n" . hash_to_text($value, $indent + 1, $seen) . "\n$spaces";
  294. }
  295. elsif (ref $value eq 'ARRAY') {
  296. $formatted_value = array_to_text($value, $indent + 1, $seen);
  297. }
  298. elsif (ref $value) {
  299. $formatted_value = '[' . ref($value) . ']';
  300. }
  301. elsif (!defined $value) {
  302. $formatted_value = '';
  303. }
  304. else {
  305. $formatted_value = "'$value'";
  306. }
  307. push @lines, "$spaces $formatted_key => $formatted_value" if ($formatted_value);
  308. }
  309. return join(",\n", @lines) || "$spaces # empty";
  310. }
  311. else {
  312. return "'$hash_ref'";
  313. }
  314. }
  315. #---------------------------------------------------------------------------------------------------------
  316. sub array_to_text {
  317. my ($array_ref, $indent, $seen) = @_;
  318. $indent ||= 0;
  319. $seen ||= {};
  320. return '[]' unless @$array_ref;
  321. my $spaces = ' ' x $indent;
  322. my @lines;
  323. foreach my $item (@$array_ref) {
  324. my $formatted_item;
  325. if (ref $item eq 'HASH') {
  326. $formatted_item = ":\n" . hash_to_text($item, $indent + 1, $seen) . "\n$spaces";
  327. }
  328. elsif (ref $item eq 'ARRAY') {
  329. $formatted_item = array_to_text($item, $indent + 1, $seen);
  330. }
  331. elsif (ref $item) {
  332. $formatted_item = '[' . ref($item) . ']';
  333. }
  334. elsif (!defined $item) {
  335. $formatted_item = '';
  336. }
  337. else {
  338. $formatted_item = "'$item'";
  339. }
  340. push @lines, "$spaces $formatted_item" if ($formatted_item);
  341. }
  342. return "[\n" . join(",\n", @lines) . "\n$spaces]";
  343. }
  344. #---------------------------------------------------------------------------------------------------------
  345. # Вспомогательная функция для получения адреса ссылки
  346. sub refaddr {
  347. my $ref = shift;
  348. return "$ref" =~ /\(0x([0-9a-f]+)\)$/ ? "0x$1" : "$ref";
  349. }
  350. #---------------------------------------------------------------------------------------------------------
  351. ### Check few run script
  352. sub IsNotRun {
  353. my $pname = shift;
  354. my $lockfile = $pname.".pid";
  355. # if pid file not exists - OK
  356. log_debug("Check what pid file $lockfile exists.");
  357. if (! -e $lockfile) { log_debug("pid file not found. Continue."); return 1; }
  358. open (FF,"<$lockfile") or log_die("can't open file $lockfile: $!");
  359. my $lockid = <FF>;
  360. close(FF);
  361. chomp($lockid);
  362. # If the process ID belongs to the current program - OK
  363. if ($lockid eq $$) { log_debug("pid file found, but owner is this process. Continue. "); return 1; }
  364. # if owner of this process ID not exists - OK
  365. my $process_count = `ps -p $lockid | grep \'$lockid\' | wc -l`;
  366. chomp($process_count);
  367. log_debug("Process count with id $lockid is $process_count");
  368. if ($process_count==0) { log_debug("pid file found, but owner process not found. Remove lock file and continue. "); unlink $lockfile; return 1; }
  369. log_debug("Another proceess with name $MY_NAME pid: $lockid already worked. ");
  370. return 0;
  371. }
  372. #---------------------------------------------------------------------------------------------------------
  373. sub IsMyPID {
  374. my $pname = shift;
  375. my $lockfile = $pname.".pid";
  376. log_debug("Check what pid file $lockfile exists.");
  377. if (! -e $lockfile) { log_debug("pid file not found. Continue."); return 1; }
  378. open (FF,"<$lockfile") or log_die "can't open file $lockfile: $!";
  379. my $lockid = <FF>;
  380. close(FF);
  381. chomp($lockid);
  382. if ($lockid eq $$) { log_debug("pid file is my. continue."); return 1; }
  383. log_debug("Another proceess with name $MY_NAME pid: $lockid already worked. ");
  384. return 0;
  385. }
  386. #---------------------------------------------------------------------------------------------------------
  387. sub Add_PID {
  388. my $pname = shift;
  389. my $lockfile = $pname.".pid";
  390. log_debug("Try create lock file $lockfile");
  391. open (FF,">$lockfile") or log_die "can't open file $lockfile: $!";
  392. flock(FF,2) or log_die "can't flock $lockfile: $!";
  393. print FF $$;
  394. close(FF);
  395. log_debug("Ok.");
  396. return 1;
  397. }
  398. #---------------------------------------------------------------------------------------------------------
  399. sub Remove_PID {
  400. my $pname = shift;
  401. my $lockfile = $pname.".pid";
  402. log_debug("Check what pid file $lockfile exists.");
  403. if (! -e $lockfile) { log_debug("pid file not exists. Continue."); return 1; }
  404. unlink $lockfile or return 0;
  405. log_debug("pid file $lockfile removed.");
  406. return 1;
  407. }
  408. #---------------------------------------------------------------------------------------------------------
  409. sub IsNotLocked {
  410. my $lockfile = $_[0] . ".lock";
  411. log_debug("Check what lock file $lockfile exists.");
  412. if (! -e $lockfile) { log_debug("lock file not found. Continue."); return 1; }
  413. open (FF,"<$lockfile") or log_die "can't open file $lockfile: $!";
  414. my $lockid = <FF>;
  415. close(FF);
  416. chomp($lockid);
  417. if ($lockid eq $$) { log_debug("lock file found, but it is owner is this process. Continue. "); return 1; }
  418. my $process_count = `ps -p $lockid | grep \'$lockid\' | wc -l`;
  419. if ($process_count lt 1) { log_debug("lock file found, but owner process not found. Remove lock file and continue. "); unlink $lockfile; return 1; }
  420. log_debug("Another proceess with pid: $lockid already use $_[0]");
  421. return 0;
  422. }
  423. #---------------------------------------------------------------------------------------------------------
  424. sub IsMyLock {
  425. my $lockfile = $_[0] . ".lock";
  426. log_debug("Check what lock file $lockfile exists.");
  427. if (! -e $lockfile) { log_debug("lock file not found. Continue."); return 0; }
  428. open (FF,"<$lockfile") or log_die "can't open file $lockfile: $!";
  429. my $lockid = <FF>;
  430. close(FF);
  431. chomp($lockid);
  432. if ($lockid eq $$) { log_debug("lock file found, but it is owner is this process. Continue. "); return 1; }
  433. log_debug("file $_[0] used by process with pid: $lockid");
  434. return 0;
  435. }
  436. #---------------------------------------------------------------------------------------------------------
  437. sub Add_Lock {
  438. if (!IsNotLocked($_[0])) { return 0; }
  439. my $lockfile = $_[0] . ".lock";
  440. open (FF,">$lockfile") or log_die "can't open file $lockfile: $!";
  441. flock(FF,2) or log_die "can't flock $lockfile: $!";
  442. print FF $$;
  443. close(FF);
  444. log_debug("Create lock file for $_[0]");
  445. return 1;
  446. }
  447. #---------------------------------------------------------------------------------------------------------
  448. sub Remove_Lock {
  449. if (!IsNotLocked($_[0])) { return 0; }
  450. my $lockfile = $_[0] . ".lock";
  451. if (! -e $lockfile) { return 1; }
  452. unlink $lockfile or return 0;
  453. log_debug("Lock file for $_[0] removed");
  454. return 1;
  455. }
  456. #---------------------------------------------------------------------------------------------------------
  457. sub DefHash {
  458. my $hash=$_[0];
  459. my $num_list = $_[1];
  460. my %num_keys;
  461. if ($num_list) {
  462. my @ret_num = split(' ',$num_list);
  463. %num_keys = map { $_, 1 } @ret_num;
  464. }
  465. foreach my $key (keys %$hash) {
  466. my $null_value = "";
  467. $null_value = 0 if (defined $num_keys{$key});
  468. $hash->{$key}=$null_value if (!defined($hash->{$key}));
  469. }
  470. return $hash;
  471. }
  472. #---------------------------------------------------------------------------------------------------------
  473. sub read_file {
  474. my $filename = shift;
  475. return if (!$filename);
  476. return if (!-e $filename);
  477. open (FF,"<$filename") or die "unable to open file $filename!" ;
  478. my @tmp=<FF>;
  479. close(FF);
  480. chomp(@tmp);
  481. return @tmp;
  482. }
  483. #---------------------------------------------------------------------------------------------------------
  484. sub uniq (\@) {
  485. my @tmp = @{(shift)};
  486. if (scalar(@tmp) eq 0) { return @tmp; }
  487. chomp(@tmp);
  488. my %newlist = map { $_, 1 } @tmp;
  489. return keys %newlist;
  490. }
  491. #---------------------------------------------------------------------------------------------------------
  492. sub strim {
  493. my $str=shift;
  494. return if (!$str);
  495. #$str =~ s/.*[^[:print:]]+//g;
  496. #$str =~ s/[^[:print:]]+//g;
  497. #$str =~ s/[^(a-z|A-Z|0-9|\:|\-|\s|\.)]//g;
  498. #$str =~ s/[:^print:]//g;
  499. $str =~ s/[^[:ascii:]]//g;
  500. $str =~ s/^\s+//g;
  501. $str =~ s/\s+$//g;
  502. return $str;
  503. }
  504. #---------------------------------------------------------------------------------------------------------
  505. sub trim {
  506. my $str=shift;
  507. return if (!$str);
  508. $str =~ s/\n/ /g;
  509. $str =~ s/^\s+//g;
  510. $str =~ s/\s+$//g;
  511. return $str;
  512. }
  513. #---------------------------------------------------------------------------------------------------------
  514. sub is_integer {
  515. defined $_[0] && $_[0] =~ /^[+-]?\d+$/;
  516. }
  517. #---------------------------------------------------------------------------------------------------------
  518. sub is_float {
  519. defined $_[0] && $_[0] =~ /^[+-]?\d+(\.\d+)?$/;
  520. }
  521. #---------------------------------------------------------------------------------------------------------
  522. sub run_in_parallel(\@) {
  523. my @commands = @{(shift)};
  524. my @result = ();
  525. return @result if (!@commands or !scalar(@commands));
  526. my $count = scalar(@commands);
  527. my $start = 0;
  528. while ($start<=$count-1) {
  529. my @run_list=();
  530. my $select = IO::Select->new();
  531. my $stop = $start + $parallel_process_count;
  532. $stop=$count-1 if ($stop >=$count);
  533. for (my $index = $start; $index <=$stop; $index++) {
  534. next if (!$commands[$index]);
  535. my $cmd=$commands[$index];
  536. log_info("Starting ".$cmd);
  537. my ($hchild, $hparent, $childid);
  538. socketpair($hchild, $hparent, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or die "socketpair: $!";
  539. $childid = fork;
  540. die "cannot fork" if($childid == -1);
  541. # redirect child Input|Output
  542. unless($childid) {
  543. open STDIN, "<&", $hparent;
  544. open STDOUT, ">&", $hparent;
  545. open STDERR, ">&", $hparent;
  546. close $hparent;
  547. close $hchild;
  548. $select->remove($_) and close $_ for($select->handles);
  549. exec "/bin/nice -n 15 ".$cmd;
  550. }
  551. close $hparent;
  552. $select->add($hchild);
  553. }
  554. while (my @ready = $select->can_read) {
  555. next if (!@ready or !scalar(@ready));
  556. for my $read(@ready) {
  557. if($read->eof || $read->error) {
  558. # child exit
  559. $select->remove($read);
  560. close $read;
  561. next;
  562. }
  563. if(defined(my $str = <$read>)) {
  564. log_info("Read:".$str);
  565. push(@result,$str);
  566. }
  567. }
  568. }
  569. $start = $stop+1;
  570. }
  571. return (@result);
  572. }
  573. #---------------------------------------------------------------------------------
  574. sub translit {
  575. my $textline=shift;
  576. return if (!$textline);
  577. $textline =~ s/А/A/g; $textline =~ s/а/a/g;
  578. $textline =~ s/Б/B/g; $textline =~ s/б/b/g;
  579. $textline =~ s/В/V/g; $textline =~ s/в/v/g;
  580. $textline =~ s/Г/G/g; $textline =~ s/г/g/g;
  581. $textline =~ s/Д/D/g; $textline =~ s/д/d/g;
  582. $textline =~ s/Е/E/g; $textline =~ s/е/e/g;
  583. $textline =~ s/Ё/E/g; $textline =~ s/ё/e/g;
  584. $textline =~ s/Ж/Zh/g; $textline =~ s/ж/zh/g;
  585. $textline =~ s/З/Z/g; $textline =~ s/з/z/g;
  586. $textline =~ s/И/I/g; $textline =~ s/и/i/g;
  587. $textline =~ s/Й/I/g; $textline =~ s/й/i/g;
  588. $textline =~ s/К/K/g; $textline =~ s/к/k/g;
  589. $textline =~ s/Л/L/g; $textline =~ s/л/l/g;
  590. $textline =~ s/М/M/g; $textline =~ s/м/m/g;
  591. $textline =~ s/Н/N/g; $textline =~ s/н/n/g;
  592. $textline =~ s/О/O/g; $textline =~ s/о/o/g;
  593. $textline =~ s/П/P/g; $textline =~ s/п/p/g;
  594. $textline =~ s/Р/R/g; $textline =~ s/р/r/g;
  595. $textline =~ s/ТС/T-S/g; $textline =~ s/Тс/T-s/g; $textline =~ s/тс/t-s/g;
  596. $textline =~ s/С/S/g; $textline =~ s/с/s/g;
  597. $textline =~ s/Т/T/g; $textline =~ s/т/t/g;
  598. $textline =~ s/У/U/g; $textline =~ s/у/u/g;
  599. $textline =~ s/Ф/F/g; $textline =~ s/ф/f/g;
  600. $textline =~ s/Х/Kh/g; $textline =~ s/х/kh/g;
  601. $textline =~ s/Ц/Ts/g; $textline =~ s/ц/ts/g;
  602. $textline =~ s/Ч/Ch/g; $textline =~ s/ч/ch/g;
  603. $textline =~ s/Ш/Sh/g; $textline =~ s/ш/sh/g;
  604. $textline =~ s/Щ/Shch/g; $textline =~ s/щ/shch/g;
  605. #$textline =~ s/Ь/'/g; $textline =~ s/ь/'/g;
  606. #$textline =~ s/Ъ/''/g; $textline =~ s/ъ/''/g;
  607. $textline =~ s/Ь//g; $textline =~ s/ь//g;
  608. $textline =~ s/Ъ//g; $textline =~ s/ъ//g;
  609. $textline =~ s/Ы/Y/g; $textline =~ s/ы/y/g;
  610. $textline =~ s/Э/E/g; $textline =~ s/э/e/g;
  611. $textline =~ s/Ю/Yu/g; $textline =~ s/ю/yu/g;
  612. $textline =~ s/Я/Ya/g; $textline =~ s/я/ya/g;
  613. return $textline;
  614. }
  615. #---------------------------------------------------------------------------------
  616. sub netdev_set_auth {
  617. my $device = shift;
  618. $device->{login}=$config_ref{router_login} if (!$device->{login});
  619. $device->{password}=$config_ref{router_password} if (!$device->{password});
  620. $device->{password}=decrypt_string($device->{password});
  621. $device->{enable_password}='';
  622. #$device->{enable_password}=$device->{passowrd};
  623. $device->{proto} = 'ssh';
  624. $device->{proto} = 'telnet' if ($device->{protocol} eq '1');
  625. #patch for ssh
  626. if ($device->{proto} eq 'ssh' and exists $switch_auth{$device->{vendor_id}}{proto}) {
  627. #set specified ssh type
  628. if ($switch_auth{$device->{vendor_id}}{proto} =~/ssh/i) {
  629. $device->{proto} = $switch_auth{$device->{vendor_id}}{proto};
  630. }
  631. }
  632. $device->{port} = $device->{control_port} if ($device->{control_port});
  633. $device->{prompt} = qr/[\$#>]\s?$/;
  634. if (exists $switch_auth{$device->{vendor_id}}) {
  635. $device->{prompt} = $switch_auth{$device->{vendor_id}}{prompt} if ($switch_auth{$device->{vendor_id}}{prompt});
  636. }
  637. return $device;
  638. }
  639. #---------------------------------------------------------------------------------
  640. sub decrypt_string {
  641. my $crypted_string = shift;
  642. return if (!$crypted_string);
  643. my $cipher_handle = Crypt::CBC->new(
  644. {
  645. 'key' => $config_ref{encryption_key},
  646. 'cipher' => 'Cipher::AES',
  647. 'iv' => $config_ref{encryption_iv},
  648. 'literal_key' => 1,
  649. 'header' => 'none',
  650. keysize => 128 / 8
  651. }
  652. );
  653. my $result = $cipher_handle->decrypt(decode_base64($crypted_string));
  654. return $result;
  655. }
  656. #---------------------------------------------------------------------------------
  657. sub crypt_string {
  658. my $simple_string = shift;
  659. return if (!$simple_string);
  660. my $cipher_handle = Crypt::CBC->new(
  661. {
  662. 'key' => $config_ref{encryption_key},
  663. 'cipher' => 'Cipher::AES',
  664. 'iv' => $config_ref{encryption_iv},
  665. 'literal_key' => 1,
  666. 'header' => 'none',
  667. keysize => 128 / 8
  668. }
  669. );
  670. my $result = encode_base64($cipher_handle->encrypt($simple_string));
  671. return $result;
  672. }
  673. #---------------------------------------------------------------------------------------------------------------
  674. sub GetNowTime {
  675. my ($sec,$min,$hour,$day,$month,$year,$zone) = localtime(time());
  676. $month += 1;
  677. $year += 1900;
  678. my $now_str=sprintf "%04d-%02d-%02d %02d:%02d:%02d",$year,$month,$day,$hour,$min,$sec;
  679. return $now_str;
  680. }
  681. #---------------------------------------------------------------------------------------------------------------
  682. sub GetUnixTimeByStr {
  683. my $time_str = shift;
  684. $time_str =~s/\//-/g;
  685. $time_str = trim($time_str);
  686. my ($sec,$min,$hour,$day,$mon,$year) = (localtime())[0,1,2,3,4,5];
  687. $year+=1900;
  688. $mon++;
  689. if ($time_str =~/^([0-9]{2,4})\-([0-9]{1,2})-([0-9]{1,2})\s+/) {
  690. $year = $1; $mon = $2; $day = $3;
  691. }
  692. if ($time_str =~/([0-9]{1,2})\:([0-9]{1,2})\:([0-9]{1,2})$/) {
  693. $hour = $1; $min = $2; $sec = $3;
  694. }
  695. my $result = mktime($sec,$min,$hour,$day,$mon-1,$year-1900);
  696. return $result;
  697. }
  698. #---------------------------------------------------------------------------------------------------------------
  699. sub GetTimeStrByUnixTime {
  700. my $time = shift || time();
  701. my ($sec, $min, $hour, $mday, $mon, $year) = (localtime($time))[0,1,2,3,4,5];
  702. my $result = strftime("%Y-%m-%d %H:%M:%S",$sec, $min, $hour, $mday, $mon, $year);
  703. return $result;
  704. }
  705. #---------------------------------------------------------------------------------------------------------
  706. # Helper function for HTML escaping
  707. sub htmlspecialchars {
  708. my ($text) = @_;
  709. return '' unless defined $text;
  710. $text =~ s/&/&amp;/g;
  711. $text =~ s/</&lt;/g;
  712. $text =~ s/>/&gt;/g;
  713. $text =~ s/"/&quot;/g;
  714. $text =~ s/'/&#039;/g;
  715. return $text;
  716. }
  717. #---------------------------------------------------------------------------------
  718. 1;
  719. }