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 #=====================================================================
 
  40   $main::lxdebug->enter_sub();
 
  42   my ($type, $memfile, $login) = @_;
 
  46     &error("", "$memfile locked!") if (-f "${memfile}.LCK");
 
  48     open(MEMBER, "$memfile") or &error("", "$memfile : $!");
 
  59           # remove any trailing whitespace
 
  62           ($key, $value) = split(/=/, $_, 2);
 
  64           if (($key eq "stylesheet") && ($value eq "sql-ledger.css")) {
 
  65             $value = "lx-office-erp.css";
 
  68           $self->{$key} = $value;
 
  71         $self->{login} = $login;
 
  79   $main::lxdebug->leave_sub();
 
  84   $main::lxdebug->enter_sub();
 
  89   # scan the locale directory and read in the LANGUAGE files
 
  90   opendir DIR, "locale";
 
  92   my @dir = grep !/(^\.\.?$|\..*)/, readdir DIR;
 
  94   foreach my $dir (@dir) {
 
  95     next unless open(FH, "locale/$dir/LANGUAGE");
 
  99     $cc{$dir} = "@language";
 
 104   $main::lxdebug->leave_sub();
 
 110   $main::lxdebug->enter_sub();
 
 112   my ($self, $form, $userspath) = @_;
 
 116   if ($self->{login}) {
 
 118     if ($self->{password}) {
 
 119       if ($form->{hashed_password}) {
 
 120         $form->{password} = $form->{hashed_password};
 
 122         $form->{password} = crypt($form->{password},
 
 123                                   substr($self->{login}, 0, 2));
 
 125       if ($self->{password} ne $form->{password}) {
 
 126         $main::lxdebug->leave_sub();
 
 131     unless (-e "$userspath/$self->{login}.conf") {
 
 132       $self->create_config("$userspath/$self->{login}.conf");
 
 135     do "$userspath/$self->{login}.conf";
 
 136     $myconfig{dbpasswd} = unpack 'u', $myconfig{dbpasswd};
 
 138     # check if database is down
 
 140       DBI->connect($myconfig{dbconnect}, $myconfig{dbuser},
 
 142       or $self->error(DBI::errstr);
 
 144     # we got a connection, check the version
 
 145     my $query = qq|SELECT version FROM defaults|;
 
 146     my $sth   = $dbh->prepare($query);
 
 147     $sth->execute || $form->dberror($query);
 
 149     my ($dbversion) = $sth->fetchrow_array;
 
 152     # add login to employee table if it does not exist
 
 153     # no error check for employee table, ignore if it does not exist
 
 154     $query = qq|SELECT e.id FROM employee e WHERE e.login = '$self->{login}'|;
 
 155     $sth   = $dbh->prepare($query);
 
 158     my ($login) = $sth->fetchrow_array;
 
 162       $query = qq|INSERT INTO employee (login, name, workphone, role)
 
 163                   VALUES ('$self->{login}', '$myconfig{name}',
 
 164                   '$myconfig{tel}', 'user')|;
 
 168     $self->create_schema_info_table($form, $dbh);
 
 175       parse_dbupdate_controls($form, $myconfig{"dbdriver"});
 
 177     map({ $form->{$_} = $myconfig{$_} }
 
 178         qw(dbname dbhost dbport dbdriver dbuser dbpasswd dbconnect));
 
 180     if (update_available($myconfig{"dbdriver"}, $dbversion) ||
 
 181         update2_available($form, $controls)) {
 
 183       $form->{"stylesheet"} = "lx-office-erp.css";
 
 184       $form->{"title"} = $main::locale->text("Dataset upgrade");
 
 186       print($form->parse_html_template("dbupgrade/header"));
 
 188       $form->{dbupdate} = "db$myconfig{dbname}";
 
 189       $form->{ $form->{dbupdate} } = 1;
 
 191       if ($form->{"show_dbupdate_warning"}) {
 
 192         print($form->parse_html_template("dbupgrade/warning"));
 
 197       open(FH, ">$userspath/nologin") or die("$!");
 
 199       # required for Oracle
 
 200       $form->{dbdefault} = $sid;
 
 202       # ignore HUP, QUIT in case the webserver times out
 
 203       $SIG{HUP}  = 'IGNORE';
 
 204       $SIG{QUIT} = 'IGNORE';
 
 206       $self->dbupdate($form);
 
 207       $self->dbupdate2($form, $controls);
 
 210       unlink("$userspath/nologin");
 
 213         $self->{"menustyle"} eq "v3" ? "menuv3.pl" :
 
 214         $self->{"menustyle"} eq "neu" ? "menunew.pl" :
 
 217       print($form->parse_html_template("dbupgrade/footer",
 
 218                                        { "menufile" => $menufile }));
 
 225   $main::lxdebug->leave_sub();
 
 231   $main::lxdebug->enter_sub();
 
 233   my ($form, $db) = @_;
 
 236         'Pg' => { 'yy-mm-dd'   => 'set DateStyle to \'ISO\'',
 
 237                   'yyyy-mm-dd' => 'set DateStyle to \'ISO\'',
 
 238                   'mm/dd/yy'   => 'set DateStyle to \'SQL, US\'',
 
 239                   'mm-dd-yy'   => 'set DateStyle to \'POSTGRES, US\'',
 
 240                   'dd/mm/yy'   => 'set DateStyle to \'SQL, EUROPEAN\'',
 
 241                   'dd-mm-yy'   => 'set DateStyle to \'POSTGRES, EUROPEAN\'',
 
 242                   'dd.mm.yy'   => 'set DateStyle to \'GERMAN\''
 
 245           'yy-mm-dd'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'YY-MM-DD\'',
 
 246           'yyyy-mm-dd' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'YYYY-MM-DD\'',
 
 247           'mm/dd/yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'MM/DD/YY\'',
 
 248           'mm-dd-yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'MM-DD-YY\'',
 
 249           'dd/mm/yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD/MM/YY\'',
 
 250           'dd-mm-yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD-MM-YY\'',
 
 251           'dd.mm.yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD.MM.YY\'',
 
 254   $form->{dboptions} = $dboptions{ $form->{dbdriver} }{ $form->{dateformat} };
 
 256   if ($form->{dbdriver} eq 'Pg') {
 
 257     $form->{dbconnect} = "dbi:Pg:dbname=$db";
 
 260   if ($form->{dbdriver} eq 'Oracle') {
 
 261     $form->{dbconnect} = "dbi:Oracle:sid=$form->{sid}";
 
 264   if ($form->{dbhost}) {
 
 265     $form->{dbconnect} .= ";host=$form->{dbhost}";
 
 267   if ($form->{dbport}) {
 
 268     $form->{dbconnect} .= ";port=$form->{dbport}";
 
 271   $main::lxdebug->leave_sub();
 
 275   $main::lxdebug->enter_sub();
 
 277   my @drivers = DBI->available_drivers();
 
 279   $main::lxdebug->leave_sub();
 
 281   return (grep { /(Pg|Oracle)/ } @drivers);
 
 285   $main::lxdebug->enter_sub();
 
 287   my ($self, $form) = @_;
 
 292   $form->{dbdefault} = $form->{dbuser} unless $form->{dbdefault};
 
 293   $form->{sid} = $form->{dbdefault};
 
 294   &dbconnect_vars($form, $form->{dbdefault});
 
 297     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 300   if ($form->{dbdriver} eq 'Pg') {
 
 302     $query = qq|SELECT datname FROM pg_database WHERE NOT ((datname = 'template0') OR (datname = 'template1'))|;
 
 303     $sth   = $dbh->prepare($query);
 
 304     $sth->execute || $form->dberror($query);
 
 306     while (my ($db) = $sth->fetchrow_array) {
 
 308       if ($form->{only_acc_db}) {
 
 310         next if ($db =~ /^template/);
 
 312         &dbconnect_vars($form, $db);
 
 314           DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 317         $query = qq|SELECT p.tablename FROM pg_tables p
 
 318                     WHERE p.tablename = 'defaults'
 
 319                     AND p.tableowner = '$form->{dbuser}'|;
 
 320         my $sth = $dbh->prepare($query);
 
 321         $sth->execute || $form->dberror($query);
 
 323         if ($sth->fetchrow_array) {
 
 324           push @dbsources, $db;
 
 330       push @dbsources, $db;
 
 334   if ($form->{dbdriver} eq 'Oracle') {
 
 335     if ($form->{only_acc_db}) {
 
 336       $query = qq|SELECT o.owner FROM dba_objects o
 
 337                   WHERE o.object_name = 'DEFAULTS'
 
 338                   AND o.object_type = 'TABLE'|;
 
 340       $query = qq|SELECT username FROM dba_users|;
 
 343     $sth = $dbh->prepare($query);
 
 344     $sth->execute || $form->dberror($query);
 
 346     while (my ($db) = $sth->fetchrow_array) {
 
 347       push @dbsources, $db;
 
 354   $main::lxdebug->leave_sub();
 
 360   $main::lxdebug->enter_sub();
 
 362   my ($self, $form) = @_;
 
 364   $form->{sid} = $form->{dbdefault};
 
 365   &dbconnect_vars($form, $form->{dbdefault});
 
 367     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 371     'Pg'     => qq|CREATE DATABASE "$form->{db}"|,
 
 373       qq|CREATE USER "$form->{db}" DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP IDENTIFIED BY "$form->{db}"|
 
 380   push(@{$dboptions{"Pg"}}, "ENCODING = " . $dbh->quote($form->{"encoding"}))
 
 381     if ($form->{"encoding"});
 
 382   if ($form->{"dbdefault"}) {
 
 383     my $dbdefault = $form->{"dbdefault"};
 
 384     $dbdefault =~ s/[^a-zA-Z0-9_\-]//g;
 
 385     push(@{$dboptions{"Pg"}}, "TEMPLATE = $dbdefault");
 
 388   my $query = qq|$dbcreate{$form->{dbdriver}}|;
 
 389   $query .= " WITH " . join(" ", @{$dboptions{"Pg"}}) if (@{$dboptions{"Pg"}});
 
 391   $dbh->do($query) || $form->dberror($query);
 
 393   if ($form->{dbdriver} eq 'Oracle') {
 
 394     $query = qq|GRANT CONNECT,RESOURCE TO "$form->{db}"|;
 
 395     $dbh->do($query) || $form->dberror($query);
 
 399   # setup variables for the new database
 
 400   if ($form->{dbdriver} eq 'Oracle') {
 
 401     $form->{dbuser}   = $form->{db};
 
 402     $form->{dbpasswd} = $form->{db};
 
 405   &dbconnect_vars($form, $form->{db});
 
 407   $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 411   my $filename = qq|sql/lx-office.sql|;
 
 412   $self->process_query($form, $dbh, $filename);
 
 415   ($filename) = split /_/, $form->{chart};
 
 417   $self->process_query($form, $dbh, "sql/${filename}-gifi.sql");
 
 419   # load chart of accounts
 
 420   $filename = qq|sql/$form->{chart}-chart.sql|;
 
 421   $self->process_query($form, $dbh, $filename);
 
 423   $query = "UPDATE defaults SET coa = " . $dbh->quote($form->{"chart"});
 
 424   $dbh->do($query) || $form->dberror($query);
 
 428   $main::lxdebug->leave_sub();
 
 431 # Process a Perl script which updates the database.
 
 432 # If the script returns 1 then the update was successful.
 
 433 # Return code "2" means "needs more interaction; remove
 
 434 # users/nologin and exit".
 
 435 # All other return codes are fatal errors.
 
 436 sub process_perl_script {
 
 437   $main::lxdebug->enter_sub();
 
 439   my ($self, $form, $dbh, $filename, $version_or_control) = @_;
 
 441   open(FH, "$filename") or $form->error("$filename : $!\n");
 
 442   my $contents = join("", <FH>);
 
 447   my %dbup_myconfig = ();
 
 448   map({ $dbup_myconfig{$_} = $form->{$_}; }
 
 449       qw(dbname dbuser dbpasswd dbhost dbport dbconnect));
 
 451   my $nls_file = $filename;
 
 452   $nls_file =~ s|.*/||;
 
 453   $nls_file =~ s|.pl$||;
 
 454   my $dbup_locale = Locale->new($main::language, $nls_file);
 
 456   my $result = eval($contents);
 
 463   if (!defined($result)) {
 
 464     print($form->parse_html_template("dbupgrade/error",
 
 465                                      { "file" => $filename,
 
 468   } elsif (1 != $result) {
 
 469     unlink("users/nologin") if (2 == $result);
 
 473   if (ref($version_or_control) eq "HASH") {
 
 474     $dbh->do("INSERT INTO schema_info (tag, login) VALUES (" .
 
 475              $dbh->quote($version_or_control->{"tag"}) . ", " .
 
 476              $dbh->quote($form->{"login"}) . ")");
 
 477   } elsif ($version_or_control) {
 
 478     $dbh->do("UPDATE defaults SET version = " .
 
 479              $dbh->quote($version_or_control));
 
 483   $main::lxdebug->leave_sub();
 
 487   $main::lxdebug->enter_sub();
 
 489   my ($self, $form, $dbh, $filename, $version_or_control) = @_;
 
 491   #  return unless (-f $filename);
 
 493   open(FH, "$filename") or $form->error("$filename : $!\n");
 
 502     # Remove DOS and Unix style line endings.
 
 508     for (my $i = 0; $i < length($_); $i++) {
 
 509       my $char = substr($_, $i, 1);
 
 511       # Are we inside a string?
 
 513         if ($char eq $quote_chars[-1]) {
 
 519         if (($char eq "'") || ($char eq "\"")) {
 
 520           push(@quote_chars, $char);
 
 522         } elsif ($char eq ";") {
 
 524           # Query is complete. Send it.
 
 526           $sth = $dbh->prepare($query);
 
 527           if (!$sth->execute()) {
 
 528             my $errstr = $dbh->errstr;
 
 531             $form->dberror("The database update/creation did not succeed. The file ${filename} containing the following query failed:<br>${query}<br>" .
 
 532                            "The error message was: ${errstr}<br>" .
 
 533                            "All changes in that file have been reverted.");
 
 546   if (ref($version_or_control) eq "HASH") {
 
 547     $dbh->do("INSERT INTO schema_info (tag, login) VALUES (" .
 
 548              $dbh->quote($version_or_control->{"tag"}) . ", " .
 
 549              $dbh->quote($form->{"login"}) . ")");
 
 550   } elsif ($version_or_control) {
 
 551     $dbh->do("UPDATE defaults SET version = " .
 
 552              $dbh->quote($version_or_control));
 
 558   $main::lxdebug->leave_sub();
 
 562   $main::lxdebug->enter_sub();
 
 564   my ($self, $form) = @_;
 
 566   my %dbdelete = ('Pg'     => qq|DROP DATABASE "$form->{db}"|,
 
 567                   'Oracle' => qq|DROP USER $form->{db} CASCADE|);
 
 569   $form->{sid} = $form->{dbdefault};
 
 570   &dbconnect_vars($form, $form->{dbdefault});
 
 572     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 574   my $query = qq|$dbdelete{$form->{dbdriver}}|;
 
 575   $dbh->do($query) || $form->dberror($query);
 
 579   $main::lxdebug->leave_sub();
 
 582 sub dbsources_unused {
 
 583   $main::lxdebug->enter_sub();
 
 585   my ($self, $form, $memfile) = @_;
 
 590   $form->error('File locked!') if (-f "${memfile}.LCK");
 
 593   open(FH, "$memfile") or $form->error("$memfile : $!");
 
 597       my ($null, $item) = split(/=/);
 
 604   $form->{only_acc_db} = 1;
 
 605   my @db = &dbsources("", $form);
 
 607   push @dbexcl, $form->{dbdefault};
 
 609   foreach $item (@db) {
 
 610     unless (grep /$item$/, @dbexcl) {
 
 611       push @dbsources, $item;
 
 615   $main::lxdebug->leave_sub();
 
 621   $main::lxdebug->enter_sub();
 
 623   my ($self, $form) = @_;
 
 628   $form->{sid} = $form->{dbdefault};
 
 629   &dbconnect_vars($form, $form->{dbdefault});
 
 632     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 635   if ($form->{dbdriver} eq 'Pg') {
 
 637     $query = qq|SELECT d.datname FROM pg_database d, pg_user u
 
 638                 WHERE d.datdba = u.usesysid
 
 639                 AND u.usename = '$form->{dbuser}'|;
 
 640     my $sth = $dbh->prepare($query);
 
 641     $sth->execute || $form->dberror($query);
 
 643     while (my ($db) = $sth->fetchrow_array) {
 
 645       next if ($db =~ /^template/);
 
 647       &dbconnect_vars($form, $db);
 
 650         DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 653       $query = qq|SELECT t.tablename FROM pg_tables t
 
 654                   WHERE t.tablename = 'defaults'|;
 
 655       my $sth = $dbh->prepare($query);
 
 656       $sth->execute || $form->dberror($query);
 
 658       if ($sth->fetchrow_array) {
 
 659         $query = qq|SELECT version FROM defaults|;
 
 660         my $sth = $dbh->prepare($query);
 
 663         if (my ($version) = $sth->fetchrow_array) {
 
 664           $dbsources{$db} = $version;
 
 674   if ($form->{dbdriver} eq 'Oracle') {
 
 675     $query = qq|SELECT o.owner FROM dba_objects o
 
 676                 WHERE o.object_name = 'DEFAULTS'
 
 677                 AND o.object_type = 'TABLE'|;
 
 679     $sth = $dbh->prepare($query);
 
 680     $sth->execute || $form->dberror($query);
 
 682     while (my ($db) = $sth->fetchrow_array) {
 
 684       $form->{dbuser} = $db;
 
 685       &dbconnect_vars($form, $db);
 
 688         DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 691       $query = qq|SELECT version FROM defaults|;
 
 692       my $sth = $dbh->prepare($query);
 
 695       if (my ($version) = $sth->fetchrow_array) {
 
 696         $dbsources{$db} = $version;
 
 706   $main::lxdebug->leave_sub();
 
 713   $main::lxdebug->enter_sub(2);
 
 715   my (@v, $version, $i);
 
 717   @v = split(/\./, $_[0]);
 
 718   while (scalar(@v) < 4) {
 
 722   for ($i = 0; $i < 4; $i++) {
 
 727   $main::lxdebug->leave_sub(2);
 
 731 sub cmp_script_version {
 
 732   my ($a_from, $a_to, $b_from, $b_to);
 
 733   my ($i, $res_a, $res_b);
 
 734   my ($my_a, $my_b) = ($a, $b);
 
 736   $my_a =~ s/.*-upgrade-//;
 
 738   $my_b =~ s/.*-upgrade-//;
 
 740   ($my_a_from, $my_a_to) = split(/-/, $my_a);
 
 741   ($my_b_from, $my_b_to) = split(/-/, $my_b);
 
 743   $res_a = calc_version($my_a_from);
 
 744   $res_b = calc_version($my_b_from);
 
 746   if ($res_a == $res_b) {
 
 747     $res_a = calc_version($my_a_to);
 
 748     $res_b = calc_version($my_b_to);
 
 751   return $res_a <=> $res_b;
 
 755 sub update_available {
 
 756   my ($dbdriver, $cur_version) = @_;
 
 758   opendir SQLDIR, "sql/${dbdriver}-upgrade" or &error("", "sql/${dbdriver}-upgrade: $!");
 
 760     grep(/$form->{dbdriver}-upgrade-\Q$cur_version\E.*\.(sql|pl)$/, readdir(SQLDIR));
 
 763   return ($#upgradescripts > -1);
 
 766 sub create_schema_info_table {
 
 767   $main::lxdebug->enter_sub();
 
 769   my ($self, $form, $dbh) = @_;
 
 771   my $query = "SELECT tag FROM schema_info LIMIT 1";
 
 772   if (!$dbh->do($query)) {
 
 774       "CREATE TABLE schema_info (" .
 
 777       "  itime timestamp DEFAULT now(), " .
 
 778       "  PRIMARY KEY (tag))";
 
 779     $dbh->do($query) || $form->dberror($query);
 
 782   $main::lxdebug->leave_sub();
 
 786   $main::lxdebug->enter_sub();
 
 788   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" or &error("", "sql/" . $form->{dbdriver} . "-upgrade : $!");
 
 802       sort(cmp_script_version
 
 803            grep(/$form->{dbdriver}-upgrade-.*?\.(sql|pl)$/, readdir(SQLDIR)));
 
 808   foreach my $db (split / /, $form->{dbupdate}) {
 
 810     next unless $form->{$db};
 
 812     # strip db from dataset
 
 814     &dbconnect_vars($form, $db);
 
 817       DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 821     $query = qq|SELECT version FROM defaults|;
 
 822     my $sth = $dbh->prepare($query);
 
 824     # no error check, let it fall through
 
 827     my $version = $sth->fetchrow_array;
 
 830     next unless $version;
 
 833     $version = calc_version($version);
 
 836     foreach my $upgradescript (@upgradescripts) {
 
 837       my $a = $upgradescript;
 
 838       $a =~ s/^$form->{dbdriver}-upgrade-|\.(sql|pl)$//g;
 
 841       my ($mindb, $maxdb) = split /-/, $a;
 
 842       my $str_maxdb = $maxdb;
 
 844       $mindb = calc_version($mindb);
 
 845       $maxdb = calc_version($maxdb);
 
 848       next if ($version >= $maxdb);
 
 850       # if there is no upgrade script exit
 
 851       last if ($version < $mindb);
 
 854       $main::lxdebug->message(DEBUG2, "Applying Update $upgradescript");
 
 855       if ($file_type eq "sql") {
 
 856         $self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} . "-upgrade/$upgradescript", $str_maxdb);
 
 858         $self->process_perl_script($form, $dbh, "sql/" . $form->{"dbdriver"} . "-upgrade/$upgradescript", $str_maxdb);
 
 870   $main::lxdebug->leave_sub();
 
 876   $main::lxdebug->enter_sub();
 
 878   my ($self, $form, $controls) = @_;
 
 880   $form->{sid} = $form->{dbdefault};
 
 882   my @upgradescripts = ();
 
 883   my ($query, $sth, $tag);
 
 886   @upgradescripts = sort_dbupdate_controls($controls);
 
 888   foreach my $db (split / /, $form->{dbupdate}) {
 
 890     next unless $form->{$db};
 
 892     # strip db from dataset
 
 894     &dbconnect_vars($form, $db);
 
 897       DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 900     map({ $_->{"applied"} = 0; } @upgradescripts);
 
 902     $query = "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->{"file"} =~ /\.(sql|pl)$/;
 
 927       $main::lxdebug->message(DEBUG2, "Applying Update $control->{file}");
 
 928       print($form->parse_html_template("dbupgrade/upgrade_message2",
 
 931       if ($file_type eq "sql") {
 
 932         $self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 933                              "-upgrade2/$control->{file}", $control);
 
 935         $self->process_perl_script($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 936                                    "-upgrade2/$control->{file}", $control);
 
 945   $main::lxdebug->leave_sub();
 
 950 sub update2_available {
 
 951   $main::lxdebug->enter_sub();
 
 953   my ($form, $controls) = @_;
 
 955   map({ $_->{"applied"} = 0; } values(%{$controls}));
 
 957   dbconnect_vars($form, $form->{"dbname"});
 
 960     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) ||
 
 963   my ($query, $tag, $sth);
 
 965   $query = "SELECT tag FROM schema_info";
 
 966   $sth = $dbh->prepare($query);
 
 967   $sth->execute() || $form->dberror($query);
 
 968   while (($tag) = $sth->fetchrow_array()) {
 
 969     $controls->{$tag}->{"applied"} = 1 if (defined($controls->{$tag}));
 
 974   map({ $main::lxdebug->leave_sub() and return 1 if (!$_->{"applied"}) }
 
 975       values(%{$controls}));
 
 977   $main::lxdebug->leave_sub();
 
 982   $main::lxdebug->enter_sub();
 
 984   my ($self, $filename) = @_;
 
 986   @config = &config_vars;
 
 988   open(CONF, ">$filename") or $self->error("$filename : $!");
 
 990   # create the config file
 
 991   print CONF qq|# configuration file for $self->{login}
 
 996   foreach $key (sort @config) {
 
 997     $self->{$key} =~ s/\'/\\\'/g;
 
 998     print CONF qq|  $key => '$self->{$key}',\n|;
 
1001   print CONF qq|);\n\n|;
 
1005   $main::lxdebug->leave_sub();
 
1009   $main::lxdebug->enter_sub();
 
1011   my ($self, $memberfile, $userspath) = @_;
 
1015   # format dbconnect and dboptions string
 
1016   &dbconnect_vars($self, $self->{dbname});
 
1018   $self->error('File locked!') if (-f "${memberfile}.LCK");
 
1019   open(FH, ">${memberfile}.LCK") or $self->error("${memberfile}.LCK : $!");
 
1022   open(CONF, "+<$memberfile") or $self->error("$memberfile : $!");
 
1029   while ($line = shift @config) {
 
1030     if ($line =~ /^\[$self->{login}\]/) {
 
1037   # remove everything up to next login or EOF
 
1038   while ($line = shift @config) {
 
1039     last if ($line =~ /^\[/);
 
1042   # this one is either the next login or EOF
 
1045   while ($line = shift @config) {
 
1049   print CONF qq|[$self->{login}]\n|;
 
1051   if ((($self->{dbpasswd} ne $self->{old_dbpasswd}) || $newmember)
 
1053     $self->{dbpasswd} = pack 'u', $self->{dbpasswd};
 
1054     chop $self->{dbpasswd};
 
1056   if (defined($self->{new_password})) {
 
1057     if ($self->{new_password} ne $self->{old_password}) {
 
1058       $self->{password} = crypt $self->{new_password},
 
1059         substr($self->{login}, 0, 2)
 
1060         if $self->{new_password};
 
1063     if ($self->{password} ne $self->{old_password}) {
 
1064       $self->{password} = crypt $self->{password}, substr($self->{login}, 0, 2)
 
1065         if $self->{password};
 
1069   if ($self->{'root login'}) {
 
1070     @config = ("password");
 
1072     @config = &config_vars;
 
1075   # replace \r\n with \n
 
1076   map { $self->{$_} =~ s/\r\n/\\n/g } qw(address signature);
 
1077   foreach $key (sort @config) {
 
1078     print CONF qq|$key=$self->{$key}\n|;
 
1083   unlink "${memberfile}.LCK";
 
1086   $self->create_config("$userspath/$self->{login}.conf")
 
1087     unless $self->{'root login'};
 
1089   $main::lxdebug->leave_sub();
 
1093   $main::lxdebug->enter_sub();
 
1095   my @conf = qw(acs address admin businessnumber charset company countrycode
 
1096     currency dateformat dbconnect dbdriver dbhost dbport dboptions
 
1097     dbname dbuser dbpasswd email fax name numberformat password
 
1098     printer role sid signature stylesheet tel templates vclimit angebote bestellungen rechnungen
 
1099     anfragen lieferantenbestellungen einkaufsrechnungen taxnumber co_ustid duns menustyle
 
1100     template_format default_media default_printer_id copies show_form_details);
 
1102   $main::lxdebug->leave_sub();
 
1108   $main::lxdebug->enter_sub();
 
1110   my ($self, $msg) = @_;
 
1112   if ($ENV{HTTP_USER_AGENT}) {
 
1113     print qq|Content-Type: text/html
 
1115 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
 
1117 <body bgcolor=ffffff>
 
1119 <h2><font color=red>Error!</font></h2>
 
1124   die "Error: $msg\n";
 
1126   $main::lxdebug->leave_sub();