1 #=====================================================================
 
   4 # Based on SQL-Ledger Version 2.1.9
 
   5 # Web http://www.lx-office.org
 
   7 #=====================================================================
 
   8 # SQL-Ledger Accounting
 
  11 #  Author: Dieter Simader
 
  12 #   Email: dsimader@sql-ledger.org
 
  13 #     Web: http://www.sql-ledger.org
 
  17 # This program is free software; you can redistribute it and/or modify
 
  18 # it under the terms of the GNU General Public License as published by
 
  19 # the Free Software Foundation; either version 2 of the License, or
 
  20 # (at your option) any later version.
 
  22 # This program is distributed in the hope that it will be useful,
 
  23 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  24 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  25 # GNU General Public License for more details.
 
  26 # You should have received a copy of the GNU General Public License
 
  27 # along with this program; if not, write to the Free Software
 
  28 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
  29 #=====================================================================
 
  31 # user related functions
 
  33 #=====================================================================
 
  46   $main::lxdebug->enter_sub();
 
  48   my ($type, $memfile, $login) = @_;
 
  56     &error("", "$memfile locked!") if (-f "${memfile}.LCK");
 
  58     open(MEMBER, "$memfile") or &error("", "$memfile : $!");
 
  69           # remove any trailing whitespace
 
  72           ($key, $value) = split(/=/, $_, 2);
 
  74           if (($key eq "stylesheet") && ($value eq "sql-ledger.css")) {
 
  75             $value = "lx-office-erp.css";
 
  78           $self->{$key} = $value;
 
  81         $self->{login} = $login;
 
  89   $main::lxdebug->leave_sub();
 
  94   $main::lxdebug->enter_sub();
 
 101   # scan the locale directory and read in the LANGUAGE files
 
 102   opendir(DIR, "locale");
 
 104   my @dir = grep(!/(^\.\.?$|\..*)/, readdir(DIR));
 
 106   foreach my $dir (@dir) {
 
 107     next unless open(FH, "locale/$dir/LANGUAGE");
 
 111     $cc{$dir} = "@language";
 
 116   $main::lxdebug->leave_sub();
 
 122   $main::lxdebug->enter_sub();
 
 124   my ($self, $form, $userspath) = @_;
 
 130   if ($self->{login}) {
 
 132     if ($self->{password}) {
 
 133       if ($form->{hashed_password}) {
 
 134         $form->{password} = $form->{hashed_password};
 
 136         $form->{password} = crypt($form->{password},
 
 137                                   substr($self->{login}, 0, 2));
 
 139       if ($self->{password} ne $form->{password}) {
 
 140         $main::lxdebug->leave_sub();
 
 145     unless (-e "$userspath/$self->{login}.conf") {
 
 146       $self->create_config();
 
 149     do "$userspath/$self->{login}.conf";
 
 150     $myconfig{dbpasswd} = unpack('u', $myconfig{dbpasswd});
 
 152     # check if database is down
 
 154       DBI->connect($myconfig{dbconnect}, $myconfig{dbuser},
 
 156       or $self->error(DBI::errstr);
 
 158     # we got a connection, check the version
 
 159     my $query = qq|SELECT version FROM defaults|;
 
 160     my $sth   = $dbh->prepare($query);
 
 161     $sth->execute || $form->dberror($query);
 
 163     my ($dbversion) = $sth->fetchrow_array;
 
 166     # add login to employee table if it does not exist
 
 167     # no error check for employee table, ignore if it does not exist
 
 168     $query = qq|SELECT id FROM employee WHERE login = ?|;
 
 169     my ($login) = selectrow_query($form, $dbh, $query, $self->{login});
 
 172       $query = qq|INSERT INTO employee (login, name, workphone, role)| .
 
 173                qq|VALUES (?, ?, ?, ?)|;
 
 174       my @values = ($self->{login}, $myconfig{name}, $myconfig{tel}, "user");
 
 175       do_query($form, $dbh, $query, @values);
 
 178     $self->create_schema_info_table($form, $dbh);
 
 185       parse_dbupdate_controls($form, $myconfig{"dbdriver"});
 
 187     map({ $form->{$_} = $myconfig{$_} }
 
 188         qw(dbname dbhost dbport dbdriver dbuser dbpasswd dbconnect));
 
 190     if (update_available($myconfig{"dbdriver"}, $dbversion) ||
 
 191         update2_available($form, $controls)) {
 
 193       $form->{"stylesheet"} = "lx-office-erp.css";
 
 194       $form->{"title"} = $main::locale->text("Dataset upgrade");
 
 196       print $form->parse_html_template("dbupgrade/header");
 
 198       $form->{dbupdate} = "db$myconfig{dbname}";
 
 199       $form->{ $form->{dbupdate} } = 1;
 
 201       if ($form->{"show_dbupdate_warning"}) {
 
 202         print $form->parse_html_template("dbupgrade/warning");
 
 207       open(FH, ">$userspath/nologin") or die("$!");
 
 209       # required for Oracle
 
 210       $form->{dbdefault} = $sid;
 
 212       # ignore HUP, QUIT in case the webserver times out
 
 213       $SIG{HUP}  = 'IGNORE';
 
 214       $SIG{QUIT} = 'IGNORE';
 
 216       $self->dbupdate($form);
 
 217       $self->dbupdate2($form, $controls);
 
 222       unlink("$userspath/nologin");
 
 225         $self->{"menustyle"} eq "v3" ? "menuv3.pl" :
 
 226         $self->{"menustyle"} eq "neu" ? "menunew.pl" :
 
 227         $self->{"menustyle"} eq "xml" ? "menuXML.pl" :
 
 230       print $form->parse_html_template("dbupgrade/footer", { "menufile" => $menufile });
 
 237   $main::lxdebug->leave_sub();
 
 243   $main::lxdebug->enter_sub();
 
 245   my ($form, $db) = @_;
 
 248         'Pg' => { 'yy-mm-dd'   => 'set DateStyle to \'ISO\'',
 
 249                   'yyyy-mm-dd' => 'set DateStyle to \'ISO\'',
 
 250                   'mm/dd/yy'   => 'set DateStyle to \'SQL, US\'',
 
 251                   'mm-dd-yy'   => 'set DateStyle to \'POSTGRES, US\'',
 
 252                   'dd/mm/yy'   => 'set DateStyle to \'SQL, EUROPEAN\'',
 
 253                   'dd-mm-yy'   => 'set DateStyle to \'POSTGRES, EUROPEAN\'',
 
 254                   'dd.mm.yy'   => 'set DateStyle to \'GERMAN\''
 
 257           'yy-mm-dd'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'YY-MM-DD\'',
 
 258           'yyyy-mm-dd' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'YYYY-MM-DD\'',
 
 259           'mm/dd/yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'MM/DD/YY\'',
 
 260           'mm-dd-yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'MM-DD-YY\'',
 
 261           'dd/mm/yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD/MM/YY\'',
 
 262           'dd-mm-yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD-MM-YY\'',
 
 263           'dd.mm.yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD.MM.YY\'',
 
 266   $form->{dboptions} = $dboptions{ $form->{dbdriver} }{ $form->{dateformat} };
 
 268   if ($form->{dbdriver} eq 'Pg') {
 
 269     $form->{dbconnect} = "dbi:Pg:dbname=$db";
 
 272   if ($form->{dbdriver} eq 'Oracle') {
 
 273     $form->{dbconnect} = "dbi:Oracle:sid=$form->{sid}";
 
 276   if ($form->{dbhost}) {
 
 277     $form->{dbconnect} .= ";host=$form->{dbhost}";
 
 279   if ($form->{dbport}) {
 
 280     $form->{dbconnect} .= ";port=$form->{dbport}";
 
 283   $main::lxdebug->leave_sub();
 
 287   $main::lxdebug->enter_sub();
 
 289   my @drivers = DBI->available_drivers();
 
 291   $main::lxdebug->leave_sub();
 
 293   return (grep { /(Pg|Oracle)/ } @drivers);
 
 297   $main::lxdebug->enter_sub();
 
 299   my ($self, $form) = @_;
 
 304   $form->{dbdefault} = $form->{dbuser} unless $form->{dbdefault};
 
 305   $form->{sid} = $form->{dbdefault};
 
 306   &dbconnect_vars($form, $form->{dbdefault});
 
 309     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 312   if ($form->{dbdriver} eq 'Pg') {
 
 314       qq|SELECT datname FROM pg_database | .
 
 315       qq|WHERE NOT datname IN ('template0', 'template1')|;
 
 316     $sth = $dbh->prepare($query);
 
 317     $sth->execute() || $form->dberror($query);
 
 319     while (my ($db) = $sth->fetchrow_array) {
 
 321       if ($form->{only_acc_db}) {
 
 323         next if ($db =~ /^template/);
 
 325         &dbconnect_vars($form, $db);
 
 327           DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 331           qq|SELECT tablename FROM pg_tables | .
 
 332           qq|WHERE (tablename = 'defaults') AND (tableowner = ?)|;
 
 333         my $sth = $dbh->prepare($query);
 
 334         $sth->execute($form->{dbuser}) ||
 
 335           $form->dberror($query . " ($form->{dbuser})");
 
 337         if ($sth->fetchrow_array) {
 
 338           push(@dbsources, $db);
 
 344       push(@dbsources, $db);
 
 348   if ($form->{dbdriver} eq 'Oracle') {
 
 349     if ($form->{only_acc_db}) {
 
 351         qq|SELECT owner FROM dba_objects | .
 
 352         qq|WHERE object_name = 'DEFAULTS' AND object_type = 'TABLE'|;
 
 354       $query = qq|SELECT username FROM dba_users|;
 
 357     $sth = $dbh->prepare($query);
 
 358     $sth->execute || $form->dberror($query);
 
 360     while (my ($db) = $sth->fetchrow_array) {
 
 361       push(@dbsources, $db);
 
 368   $main::lxdebug->leave_sub();
 
 374   $main::lxdebug->enter_sub();
 
 376   my ($self, $form) = @_;
 
 378   $form->{sid} = $form->{dbdefault};
 
 379   &dbconnect_vars($form, $form->{dbdefault});
 
 381     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 383   $form->{db} =~ s/\"//g;
 
 385     'Pg'     => qq|CREATE DATABASE "$form->{db}"|,
 
 387     qq|CREATE USER "$form->{db}" DEFAULT TABLESPACE USERS | .
 
 388     qq|TEMPORARY TABLESPACE TEMP IDENTIFIED BY "$form->{db}"|
 
 395   push(@{$dboptions{"Pg"}}, "ENCODING = " . $dbh->quote($form->{"encoding"}))
 
 396     if ($form->{"encoding"});
 
 397   if ($form->{"dbdefault"}) {
 
 398     my $dbdefault = $form->{"dbdefault"};
 
 399     $dbdefault =~ s/[^a-zA-Z0-9_\-]//g;
 
 400     push(@{$dboptions{"Pg"}}, "TEMPLATE = $dbdefault");
 
 403   my $query = $dbcreate{$form->{dbdriver}};
 
 404   $query .= " WITH " . join(" ", @{$dboptions{"Pg"}}) if (@{$dboptions{"Pg"}});
 
 406   do_query($form, $dbh, $query);
 
 408   if ($form->{dbdriver} eq 'Oracle') {
 
 409     $query = qq|GRANT CONNECT, RESOURCE TO "$form->{db}"|;
 
 410     do_query($form, $dbh, $query);
 
 414   # setup variables for the new database
 
 415   if ($form->{dbdriver} eq 'Oracle') {
 
 416     $form->{dbuser}   = $form->{db};
 
 417     $form->{dbpasswd} = $form->{db};
 
 420   &dbconnect_vars($form, $form->{db});
 
 422   $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 425   my $db_charset = $Common::db_encoding_to_charset{$form->{encoding}};
 
 426   $db_charset ||= Common::DEFAULT_CHARSET;
 
 429   $self->process_query($form, $dbh, "sql/lx-office.sql", undef, $db_charset);
 
 431   # load chart of accounts
 
 432   $self->process_query($form, $dbh, "sql/$form->{chart}-chart.sql", undef, $db_charset);
 
 434   $query = "UPDATE defaults SET coa = ?";
 
 435   do_query($form, $dbh, $query, $form->{chart});
 
 439   $main::lxdebug->leave_sub();
 
 442 # Process a Perl script which updates the database.
 
 443 # If the script returns 1 then the update was successful.
 
 444 # Return code "2" means "needs more interaction; remove
 
 445 # users/nologin and exit".
 
 446 # All other return codes are fatal errors.
 
 447 sub process_perl_script {
 
 448   $main::lxdebug->enter_sub();
 
 450   my ($self, $form, $dbh, $filename, $version_or_control, $db_charset) = @_;
 
 452   my $fh = IO::File->new($filename, "r") or $form->error("$filename : $!\n");
 
 454   my $file_charset = Common::DEFAULT_CHARSET;
 
 456   if (ref($version_or_control) eq "HASH") {
 
 457     $file_charset = $version_or_control->{charset};
 
 462       next if !/^--\s*\@charset:\s*(.+)/;
 
 466     $fh->seek(0, SEEK_SET);
 
 469   my $contents = join "", <$fh>;
 
 472   $db_charset ||= Common::DEFAULT_CHARSET;
 
 474   my $iconv = SL::Iconv::get_converter($file_charset, $db_charset);
 
 478   my %dbup_myconfig = ();
 
 479   map({ $dbup_myconfig{$_} = $form->{$_}; }
 
 480       qw(dbname dbuser dbpasswd dbhost dbport dbconnect));
 
 482   my $nls_file = $filename;
 
 483   $nls_file =~ s|.*/||;
 
 484   $nls_file =~ s|.pl$||;
 
 485   my $dbup_locale = Locale->new($main::language, $nls_file);
 
 487   my $result = eval($contents);
 
 494   if (!defined($result)) {
 
 495     print $form->parse_html_template("dbupgrade/error",
 
 496                                      { "file"  => $filename,
 
 499   } elsif (1 != $result) {
 
 500     unlink("users/nologin") if (2 == $result);
 
 504   if (ref($version_or_control) eq "HASH") {
 
 505     $dbh->do("INSERT INTO schema_info (tag, login) VALUES (" .
 
 506              $dbh->quote($version_or_control->{"tag"}) . ", " .
 
 507              $dbh->quote($form->{"login"}) . ")");
 
 508   } elsif ($version_or_control) {
 
 509     $dbh->do("UPDATE defaults SET version = " .
 
 510              $dbh->quote($version_or_control));
 
 514   $main::lxdebug->leave_sub();
 
 518   $main::lxdebug->enter_sub();
 
 520   my ($self, $form, $dbh, $filename, $version_or_control, $db_charset) = @_;
 
 522   my $fh = IO::File->new($filename, "r") or $form->error("$filename : $!\n");
 
 527   my $file_charset = Common::DEFAULT_CHARSET;
 
 530     next if !/^--\s*\@charset:\s*(.+)/;
 
 534   $fh->seek(0, SEEK_SET);
 
 536   $db_charset ||= Common::DEFAULT_CHARSET;
 
 541     $_ = SL::Iconv::convert($file_charset, $db_charset, $_);
 
 543     # Remove DOS and Unix style line endings.
 
 549     for (my $i = 0; $i < length($_); $i++) {
 
 550       my $char = substr($_, $i, 1);
 
 552       # Are we inside a string?
 
 554         if ($char eq $quote_chars[-1]) {
 
 560         if (($char eq "'") || ($char eq "\"")) {
 
 561           push(@quote_chars, $char);
 
 563         } elsif ($char eq ";") {
 
 565           # Query is complete. Send it.
 
 567           $sth = $dbh->prepare($query);
 
 568           if (!$sth->execute()) {
 
 569             my $errstr = $dbh->errstr;
 
 572             $form->dberror("The database update/creation did not succeed. " .
 
 573                            "The file ${filename} containing the following " .
 
 574                            "query failed:<br>${query}<br>" .
 
 575                            "The error message was: ${errstr}<br>" .
 
 576                            "All changes in that file have been reverted.");
 
 589   if (ref($version_or_control) eq "HASH") {
 
 590     $dbh->do("INSERT INTO schema_info (tag, login) VALUES (" .
 
 591              $dbh->quote($version_or_control->{"tag"}) . ", " .
 
 592              $dbh->quote($form->{"login"}) . ")");
 
 593   } elsif ($version_or_control) {
 
 594     $dbh->do("UPDATE defaults SET version = " .
 
 595              $dbh->quote($version_or_control));
 
 601   $main::lxdebug->leave_sub();
 
 605   $main::lxdebug->enter_sub();
 
 607   my ($self, $form) = @_;
 
 608   $form->{db} =~ s/\"//g;
 
 609   my %dbdelete = ('Pg'     => qq|DROP DATABASE "$form->{db}"|,
 
 610                   'Oracle' => qq|DROP USER "$form->{db}" CASCADE|);
 
 612   $form->{sid} = $form->{dbdefault};
 
 613   &dbconnect_vars($form, $form->{dbdefault});
 
 615     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 617   my $query = $dbdelete{$form->{dbdriver}};
 
 618   do_query($form, $dbh, $query);
 
 622   $main::lxdebug->leave_sub();
 
 625 sub dbsources_unused {
 
 626   $main::lxdebug->enter_sub();
 
 628   my ($self, $form, $memfile) = @_;
 
 635   $form->error('File locked!') if (-f "${memfile}.LCK");
 
 638   open(FH, "$memfile") or $form->error("$memfile : $!");
 
 642       my ($null, $item) = split(/=/);
 
 649   $form->{only_acc_db} = 1;
 
 650   my @db = &dbsources("", $form);
 
 652   push @dbexcl, $form->{dbdefault};
 
 654   foreach $item (@db) {
 
 655     unless (grep /$item$/, @dbexcl) {
 
 656       push @dbsources, $item;
 
 660   $main::lxdebug->leave_sub();
 
 666   $main::lxdebug->enter_sub();
 
 668   my ($self, $form) = @_;
 
 670   my $members  = Inifile->new($main::memberfile);
 
 671   my $controls = parse_dbupdate_controls($form, $form->{dbdriver});
 
 673   my ($query, $sth, %dbs_needing_updates);
 
 675   foreach my $login (grep /[a-z]/, keys %{ $members }) {
 
 676     my $member = $members->{$login};
 
 678     map { $form->{$_} = $member->{$_} } qw(dbname dbuser dbpasswd dbhost dbport);
 
 679     dbconnect_vars($form, $form->{dbname});
 
 680     $main::lxdebug->dump(0, "form", $form);
 
 681     my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd});
 
 687     $query = qq|SELECT version FROM defaults|;
 
 688     $sth = prepare_query($form, $dbh, $query);
 
 689     if ($sth->execute()) {
 
 690       ($version) = $sth->fetchrow_array();
 
 695     next unless $version;
 
 697     if (update_available($form->{dbdriver}, $version) || update2_available($form, $controls)) {
 
 699       map { $dbinfo->{$_} = $member->{$_} } grep /^db/, keys %{ $member };
 
 700       $dbs_needing_updates{$member->{dbhost} . "::" . $member->{dbname}} = $dbinfo;
 
 704   $main::lxdebug->leave_sub();
 
 706   return values %dbs_needing_updates;
 
 710   $main::lxdebug->enter_sub(2);
 
 712   my (@v, $version, $i);
 
 714   @v = split(/\./, $_[0]);
 
 715   while (scalar(@v) < 4) {
 
 719   for ($i = 0; $i < 4; $i++) {
 
 724   $main::lxdebug->leave_sub(2);
 
 728 sub cmp_script_version {
 
 729   my ($a_from, $a_to, $b_from, $b_to);
 
 730   my ($i, $res_a, $res_b);
 
 731   my ($my_a, $my_b) = ($a, $b);
 
 733   $my_a =~ s/.*-upgrade-//;
 
 735   $my_b =~ s/.*-upgrade-//;
 
 737   ($my_a_from, $my_a_to) = split(/-/, $my_a);
 
 738   ($my_b_from, $my_b_to) = split(/-/, $my_b);
 
 740   $res_a = calc_version($my_a_from);
 
 741   $res_b = calc_version($my_b_from);
 
 743   if ($res_a == $res_b) {
 
 744     $res_a = calc_version($my_a_to);
 
 745     $res_b = calc_version($my_b_to);
 
 748   return $res_a <=> $res_b;
 
 751 sub update_available {
 
 752   my ($dbdriver, $cur_version) = @_;
 
 756   opendir SQLDIR, "sql/${dbdriver}-upgrade" || error("", "sql/${dbdriver}-upgrade: $!");
 
 757   my @upgradescripts = grep /${dbdriver}-upgrade-\Q$cur_version\E.*\.(sql|pl)$/, readdir SQLDIR;
 
 760   return ($#upgradescripts > -1);
 
 763 sub create_schema_info_table {
 
 764   $main::lxdebug->enter_sub();
 
 766   my ($self, $form, $dbh) = @_;
 
 768   my $query = "SELECT tag FROM schema_info LIMIT 1";
 
 769   if (!$dbh->do($query)) {
 
 772       qq|CREATE TABLE schema_info (| .
 
 775       qq|  itime timestamp DEFAULT now(), | .
 
 776       qq|  PRIMARY KEY (tag))|;
 
 777     $dbh->do($query) || $form->dberror($query);
 
 780   $main::lxdebug->leave_sub();
 
 784   $main::lxdebug->enter_sub();
 
 786   my ($self, $form) = @_;
 
 790   $form->{sid} = $form->{dbdefault};
 
 792   my @upgradescripts = ();
 
 796   if ($form->{dbupdate}) {
 
 798     # read update scripts into memory
 
 799     opendir(SQLDIR, "sql/" . $form->{dbdriver} . "-upgrade")
 
 800       or &error("", "sql/" . $form->{dbdriver} . "-upgrade : $!");
 
 802       sort(cmp_script_version
 
 803            grep(/$form->{dbdriver}-upgrade-.*?\.(sql|pl)$/,
 
 808   my $db_charset = $main::dbcharset;
 
 809   $db_charset ||= Common::DEFAULT_CHARSET;
 
 811   foreach my $db (split(/ /, $form->{dbupdate})) {
 
 813     next unless $form->{$db};
 
 815     # strip db from dataset
 
 817     &dbconnect_vars($form, $db);
 
 820       DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 824     $query = qq|SELECT version FROM defaults|;
 
 825     my ($version) = selectrow_query($form, $dbh, $query);
 
 827     next unless $version;
 
 829     $version = calc_version($version);
 
 831     foreach my $upgradescript (@upgradescripts) {
 
 832       my $a = $upgradescript;
 
 833       $a =~ s/^\Q$form->{dbdriver}\E-upgrade-|\.(sql|pl)$//g;
 
 836       my ($mindb, $maxdb) = split /-/, $a;
 
 837       my $str_maxdb = $maxdb;
 
 838       $mindb = calc_version($mindb);
 
 839       $maxdb = calc_version($maxdb);
 
 841       next if ($version >= $maxdb);
 
 843       # if there is no upgrade script exit
 
 844       last if ($version < $mindb);
 
 847       $main::lxdebug->message(DEBUG2, "Applying Update $upgradescript");
 
 848       if ($file_type eq "sql") {
 
 849         $self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 850                              "-upgrade/$upgradescript", $str_maxdb, $db_charset);
 
 852         $self->process_perl_script($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 853                                    "-upgrade/$upgradescript", $str_maxdb, $db_charset);
 
 865   $main::lxdebug->leave_sub();
 
 871   $main::lxdebug->enter_sub();
 
 873   my ($self, $form, $controls) = @_;
 
 875   $form->{sid} = $form->{dbdefault};
 
 877   my @upgradescripts = ();
 
 878   my ($query, $sth, $tag);
 
 881   @upgradescripts = sort_dbupdate_controls($controls);
 
 883   my $db_charset = $main::dbcharset;
 
 884   $db_charset ||= Common::DEFAULT_CHARSET;
 
 886   foreach my $db (split / /, $form->{dbupdate}) {
 
 888     next unless $form->{$db};
 
 890     # strip db from dataset
 
 892     &dbconnect_vars($form, $db);
 
 895       DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 898     map({ $_->{"applied"} = 0; } @upgradescripts);
 
 900     $self->create_schema_info_table($form, $dbh);
 
 902     $query = qq|SELECT tag FROM schema_info|;
 
 903     $sth = $dbh->prepare($query);
 
 904     $sth->execute() || $form->dberror($query);
 
 905     while (($tag) = $sth->fetchrow_array()) {
 
 906       $controls->{$tag}->{"applied"} = 1 if (defined($controls->{$tag}));
 
 911     foreach (@upgradescripts) {
 
 912       if (!$_->{"applied"}) {
 
 918     next if ($all_applied);
 
 920     foreach my $control (@upgradescripts) {
 
 921       next if ($control->{"applied"});
 
 923       $control->{description} = SL::Iconv::convert($control->{charset}, $db_charset, $control->{description});
 
 925       $control->{"file"} =~ /\.(sql|pl)$/;
 
 929       $main::lxdebug->message(DEBUG2, "Applying Update $control->{file}");
 
 930       print $form->parse_html_template("dbupgrade/upgrade_message2", $control);
 
 932       if ($file_type eq "sql") {
 
 933         $self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 934                              "-upgrade2/$control->{file}", $control, $db_charset);
 
 936         $self->process_perl_script($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 937                                    "-upgrade2/$control->{file}", $control, $db_charset);
 
 946   $main::lxdebug->leave_sub();
 
 951 sub update2_available {
 
 952   $main::lxdebug->enter_sub();
 
 954   my ($form, $controls) = @_;
 
 956   map({ $_->{"applied"} = 0; } values(%{$controls}));
 
 958   dbconnect_vars($form, $form->{"dbname"});
 
 961     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) ||
 
 964   my ($query, $tag, $sth);
 
 966   $query = qq|SELECT tag FROM schema_info|;
 
 967   $sth = $dbh->prepare($query);
 
 968   if ($sth->execute()) {
 
 969     while (($tag) = $sth->fetchrow_array()) {
 
 970       $controls->{$tag}->{"applied"} = 1 if (defined($controls->{$tag}));
 
 976   map({ $main::lxdebug->leave_sub() and return 1 if (!$_->{"applied"}) }
 
 977       values(%{$controls}));
 
 979   $main::lxdebug->leave_sub();
 
 984   $main::lxdebug->enter_sub();
 
 990   @config = config_vars();
 
 992   my $userspath = $main::userspath;
 
 994   open(CONF, ">", "$userspath/$self->{login}.conf") || $self->error("$userspath/$self->{login}.conf : $!");
 
 996   # create the config file
 
 997   print CONF qq|# configuration file for $self->{login}
 
1002   foreach my $key (sort @config) {
 
1003     $self->{$key} =~ s/\'/\\\'/g;
 
1004     print CONF qq|  $key => '$self->{$key}',\n|;
 
1007   print CONF qq|);\n\n|;
 
1011   $main::lxdebug->leave_sub();
 
1015   $main::lxdebug->enter_sub();
 
1017   my ($self, $memberfile, $userspath) = @_;
 
1023   # format dbconnect and dboptions string
 
1024   &dbconnect_vars($self, $self->{dbname});
 
1026   $self->error('File locked!') if (-f "${memberfile}.LCK");
 
1027   open(FH, ">${memberfile}.LCK") or $self->error("${memberfile}.LCK : $!");
 
1030   open(CONF, "+<$memberfile") or $self->error("$memberfile : $!");
 
1037   while ($line = shift @config) {
 
1038     if ($line =~ /^\[\Q$self->{login}\E\]/) {
 
1045   # remove everything up to next login or EOF
 
1046   while ($line = shift @config) {
 
1047     last if ($line =~ /^\[/);
 
1050   # this one is either the next login or EOF
 
1053   while ($line = shift @config) {
 
1057   print CONF qq|[$self->{login}]\n|;
 
1059   if ((($self->{dbpasswd} ne $self->{old_dbpasswd}) || $newmember)
 
1061     $self->{dbpasswd} = pack 'u', $self->{dbpasswd};
 
1062     chop $self->{dbpasswd};
 
1064   if (defined($self->{new_password})) {
 
1065     if ($self->{new_password} ne $self->{old_password}) {
 
1066       $self->{password} = crypt $self->{new_password},
 
1067         substr($self->{login}, 0, 2)
 
1068         if $self->{new_password};
 
1071     if ($self->{password} ne $self->{old_password}) {
 
1072       $self->{password} = crypt $self->{password}, substr($self->{login}, 0, 2)
 
1073         if $self->{password};
 
1077   if ($self->{'root login'}) {
 
1078     @config = ("password");
 
1080     @config = &config_vars;
 
1083   # replace \r\n with \n
 
1084   map { $self->{$_} =~ s/\r\n/\\n/g } qw(address signature);
 
1085   foreach $key (sort @config) {
 
1086     print CONF qq|$key=$self->{$key}\n|;
 
1091   unlink "${memberfile}.LCK";
 
1094   $self->create_config() unless $self->{'root login'};
 
1096   $main::lxdebug->leave_sub();
 
1100   $main::lxdebug->enter_sub();
 
1102   my @conf = qw(acs address admin businessnumber company countrycode
 
1103     currency dateformat dbconnect dbdriver dbhost dbport dboptions
 
1104     dbname dbuser dbpasswd email fax name numberformat password
 
1105     printer role sid signature stylesheet tel templates vclimit angebote
 
1106     bestellungen rechnungen anfragen lieferantenbestellungen einkaufsrechnungen
 
1107     taxnumber co_ustid duns menustyle template_format default_media
 
1108     default_printer_id copies show_form_details favorites);
 
1110   $main::lxdebug->leave_sub();
 
1116   $main::lxdebug->enter_sub();
 
1118   my ($self, $msg) = @_;
 
1120   $main::lxdebug->show_backtrace();
 
1122   if ($ENV{HTTP_USER_AGENT}) {
 
1123     print qq|Content-Type: text/html
 
1125 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
 
1127 <body bgcolor=ffffff>
 
1129 <h2><font color=red>Error!</font></h2>
 
1134   die "Error: $msg\n";
 
1136   $main::lxdebug->leave_sub();