1#!/usr/bin/perl -w 2##!~_~perlpath~_~ 3# 4# Interchange version 5.6.3 5# 6# Copyright (C) 2002-2010 Interchange Development Group 7# Copyright (C) 1996-2002 Red Hat, Inc. 8# http://www.icdevgroup.org/ 9# 10# This program was originally based on Vend 0.2 and 0.3 11# Copyright 1995 by Andrew M. Wilcox <amw@wilcoxsolutions.com> 12# 13# See the files 'README' and 'WHATSNEW' for information. 14# 15# This program is free software; you can redistribute it and/or modify 16# it under the terms of the GNU General Public License as published by 17# the Free Software Foundation; either version 2 of the License, or 18# (at your option) any later version. 19# 20# This program is distributed in the hope that it will be useful, 21# but WITHOUT ANY WARRANTY; without even the implied warranty of 22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23# GNU General Public License for more details. 24# 25# You should have received a copy of the GNU General Public 26# License along with this program; if not, write to the Free 27# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, 28# MA 02110-1301 USA. 29 30use strict; 31 32BEGIN { 33 select STDERR; 34 $| = 1; 35 select STDOUT; 36 $| = 1; 37 38 if ($ENV{INTERCHANGE_INSTALLPRIVLIB}) { 39 unshift @INC, $ENV{INTERCHANGE_INSTALLPRIVLIB}; 40 } 41 else { 42 unshift @INC, '/usr/local/interchange/lib'; 43# unshift @INC, '~_~INSTALLPRIVLIB~_~'; 44 } 45 46 if ($ENV{INTERCHANGE_INSTALLARCHLIB}) { 47 unshift @INC, $ENV{INTERCHANGE_INSTALLARCHLIB}; 48 } 49 else { 50 unshift @INC, '/usr/local/interchange'; 51# unshift @INC, '~_~INSTALLARCHLIB~_~'; 52 } 53} 54 55use Config; 56no Config; 57 58BEGIN { 59 require 5.008; 60 61 $ENV{PERL_SIGNALS} ||= 'unsafe'; 62 63 $Global::Foreground = 1; 64 65 ($Global::VendRoot = $ENV{MINIVEND_ROOT}) 66 if defined $ENV{MINIVEND_ROOT}; 67 68 no warnings 'void'; 69 ## This should only happen in "make test" 70 if($Global::VendRoot =~ m{/blib$}) { 71 shift @INC; 72 shift @INC; 73 } 74 75 $Global::VendRoot = $Global::VendRoot || '/usr/local/interchange'; 76# $Global::VendRoot = $Global::VendRoot || '~_~INSTALLARCHLIB~_~'; 77 78 if( ($Config{usethreads} || $Config{useithreads} || $Config{use5005threads}) ) { 79 $Global::TryingThreads = 1; 80 } 81 82 if( $Global::TryingThreads and $] < 5.008_005 ) { 83 die "Interchange will not work with a thread-enabled perl older than Perl 5.8.5.\n"; 84 } 85 86 if(-f "$Global::VendRoot/interchange.cfg") { 87 $Global::ExeName = 'interchange'; 88 $Global::ConfigFile = 'interchange.cfg'; 89 } 90 elsif(-f "$Global::VendRoot/minivend.cfg") { 91 $Global::ExeName = 'minivend'; 92 $Global::ConfigFile = 'minivend.cfg'; 93 } 94 else { 95 $Global::ExeName = 'interchange'; 96 $Global::ConfigFile = 'interchange.cfg'; 97 } 98 99 $Global::InitialErrorFile = $Global::ErrorFile = "$Global::VendRoot/error.log"; 100 101 if($^O =~ /cygwin|win32/i) { 102 $Global::Windows = 1; 103 } 104 105 # Uncomment next line if you want to guarantee use of DB_File 106 #$ENV{MINIVEND_DBFILE} = 1; 107 108 # Uncomment next line in the unlikely event you want to ignore 109 # GDBM and DB_File and force use of SDBM. 110 #$ENV{MINIVEND_SDBM} = 1; 111 112 # Uncomment next line if you want to guarantee use of GDBM and not DB_File 113 #$ENV{MINIVEND_GDBM} = 1; 114 115 # Uncomment next line if you want to use no DBM, sessions 116 # stored in files and databases in memory (or SQL) 117 #$ENV{MINIVEND_NODBM} = 1; 118 119 # Uncomment next line if you want the ability to use ALL DBM. 120 # Otherwise we use only the first choice to save memory. 121 #$ENV{MINIVEND_ALLDBM} = 1; 122 123 # Uncomment next line if you DON'T want to use DBI, can 124 # save a bit on code size 125 #$ENV{MINIVEND_NO_DBI} = 1; 126 127 # Uncomment next line if you want to use the Storable 128 # module for storing session data. It improves session performance 129 # to a good degree. We will also do a bit of auto-detect below. 130 #$ENV{MINIVEND_STORABLE} = 1; 131 132 # Uncomment next line if you want to use the Storable 133 # module for storing database data. It improves GBDM/DB_File performance 134 # to a good degree. We will also do a bit of auto-detect below. 135 #$ENV{MINIVEND_STORABLE_DB} = 1; 136 137 # Uncomment AND SET next line to set PGP path to somewhere besides 138 # the Interchange user path 139 #$ENV{PGPPATH} = '/usr/local/pgp'; 140 141 # Use the Storable module for storing data in DBM files. 142 if(-f "$Global::VendRoot/_session_storable") { 143 $ENV{MINIVEND_STORABLE} = 1; 144 } 145 146 if(-f "$Global::VendRoot/_db_storable") { 147 $ENV{MINIVEND_STORABLE_DB} = 1; 148 } 149 150 # Interchange can use syslog via the "logger" command 151 # This prevents parsing of the value, default is syslog off 152 $Global::SysLog = ''; 153} 154 155### END CONFIGURATION VARIABLES 156 157use vars qw($VERSION); 158require Exporter; 159 160BEGIN { 161 $VERSION = '5.6.3'; 162} 163 164use Fcntl; 165 166# BSD, among others, defines sendmail to be in /usr/sbin, and 167# we want to make sure the program is there. Insert the location 168# of you sendmail binary (the configure script should do this) 169$Global::SendMailLocation = '' if ! $Global::SendMailLocation; 170$Global::SendMailLocation = ($Global::Windows and $Global::SendMailLocation) || 171 ($Global::SendMailLocation and -x $Global::SendMailLocation and $Global::SendMailLocation) || 172 (-x '/usr/sbin/sendmail' and '/usr/sbin/sendmail') || 173 (-x '/usr/lib/sendmail' and '/usr/lib/sendmail') || 174 ''; 175# '~_~sendmail~_~'; 176 177#select a DBM 178 179BEGIN { 180 $Global::GDBM = $Global::DB_File = $Global::SDBM = 181# LDAP 182 $Global::LDAP = 183# END LDAP 184# SQL 185 $Global::DBI = 186# END SQL 187 $Global::Shadow = 188 0; 189 190# SQL 191 # This is for standard DBI 192 eval { 193 die if $ENV{MINIVEND_NODBI}; 194 require DBI and $Global::DBI = 1 195 }; 196# END SQL 197# LDAP 198 eval { 199 die if $ENV{MINIVEND_NOLDAP}; 200 require Net::LDAP and $Global::LDAP = 1 201 }; 202# END LDAP 203 204 # Now can use any type of database 205 AUTO: { 206 last AUTO if 207 (defined $ENV{MINIVEND_DBFILE} and $Global::DB_File = 1); 208 last AUTO if 209 (defined $ENV{MINIVEND_SDBM} and $Global::SDBM = 1); 210 last AUTO if 211 (defined $ENV{MINIVEND_NODBM}); 212 eval {require GDBM_File and $Global::GDBM = 1}; 213 last AUTO if 214 (defined $ENV{MINIVEND_GDBM} and $Global::GDBM = 1); 215 last AUTO if 216 ! $ENV{MINIVEND_ALLDBM} 217 and $Global::GDBM; 218 eval {require DB_File and $Global::DB_File = 1}; 219 last AUTO if 220 ! $ENV{MINIVEND_ALLDBM} 221 and $Global::GDBM || $Global::DB_File; 222 eval {require SDBM_File and $Global::SDBM = 1}; 223 } 224 225 if($Global::GDBM) { 226 require Vend::Table::GDBM; 227 import GDBM_File; 228 $Global::GDBM = 1; 229 $Global::Default_database = 'GDBM' 230 unless defined $Global::Default_database; 231 } 232 if($Global::DB_File) { 233 require Vend::Table::DB_File; 234 import DB_File; 235 $Global::DB_File = 1; 236 $Global::Default_database = 'DB_FILE' 237 unless defined $Global::Default_database; 238 } 239 if($Global::SDBM) { 240 require Vend::Table::SDBM; 241 import SDBM_File; 242 $Global::SDBM = 1; 243 $Global::Default_database = 'SDBM' 244 unless defined $Global::Default_database; 245 } 246 $Global::Default_database = 'MEMORY' 247 unless defined $Global::Default_database; 248 require Vend::Table::InMemory; 249 require Vend::Table::Shadow; 250} 251 252 253use Vend::Util; 254use Vend::File; 255use Vend::Server; 256use Vend::Session; 257use Vend::Config; 258use Vend::Payment; 259use Vend::Ship; 260 261# You might try commenting out these lines and uncommenting the ones 262# below to compact memory size 263# NOAUTOUSE 264use Vend::Order; 265#use Vend::Imagemap; 266#use Vend::Error; 267#use Vend::Control; 268# END NOAUTOUSE 269 270 271# You might try commenting out these lines and uncommenting the ones 272# below to do development or test for strange problems 273# AUTOUSE 274use autouse 'Vend::Error' => qw/get_locale_message interaction_error do_lockout full_dump/; 275use autouse 'Vend::Imagemap' => qw/action_map/; 276use autouse 'Vend::Control' => qw/ 277 signal_reconfig 278 signal_add 279 signal_jobs 280 signal_remove 281 control_interchange 282 remove_catalog 283 add_catalog 284 change_catalog_directive 285 change_global_directive 286 /; 287#use autouse 'Vend::Order' => qw/ 288# add_items 289# check_order 290# check_required 291# encrypt_standard_cc 292# mail_order 293# onfly 294# route_order 295# validate_whole_cc 296# /; 297 298# END AUTOUSE 299 300use Vend::Scan; 301use Vend::Data; 302use Vend::UserDB; 303use Vend::Interpolate; 304use Vend::Page; 305use Vend::CounterFile; 306use Vend::Dispatch; 307 308if($ENV{INTERCHANGE_REQUIRE}) { 309 my @mods = split /[;\s]+/, $ENV{INTERCHANGE_REQUIRE}; 310 foreach my $mod (@mods) { 311 eval { 312 eval "require $mod"; 313 die $@ if $@; 314 }; 315 if($@) { 316 die errmsg( 317 "FAILED to require module %s as specified in environment. Error: %s\n", 318 $mod, 319 $@, 320 ); 321 } 322 else { 323 warn errmsg( 324 "Required module %s successfully as specified in environment.\n", 325 $mod, 326 ); 327 } 328 } 329} 330 331if( ! $Global::Windows and $> == -1 || scalar(getpwuid($>)) eq 'nobody' ) { 332 warn errmsg("\aYou probably don't want to run as nobody!\n"); 333 sleep 1; 334 warn errmsg("The security problems are on your head, though. Continuing...\n"); 335} 336 337## This was set to 1 in Vend::Config, so that external programs calling it 338## would act properly by default 339undef $Vend::ExternalProgram; 340 341## DEBUG 342 343sub dontwarn { 344 345 $Global::Shadow + 346 $Vend::JobsJob + 347 $Vend::Interpolate::MAIL + 348 $Vend::Server::RUNDIR + 349 350 1; 351} 352 353sub version { 354 print "Interchange version $VERSION copyright 2002-2010 Interchange Development Group and others.\n"; 355} 356 357=head1 NAME 358 359interchange - an e-commerce and general HTTP database display system 360 361=head1 SYNOPSIS 362 363interchange [--options] [file] 364 365=head1 VERSION 366 3675.6.3 368 369=head1 DESCRIPTION 370 371Interchange is a database access and retrieval system focused on e-commerce. 372It allows customers to select items to buy from catalog pages. The program 373tracks user information in sessions and interacts with an HTTP server 374through sockets. 375 376Interchange has many, many, functions and features; they are too numerous 377to describe in this venue. Complete information can be found at 378its web site: 379 380 http://www.icdevgroup.org/ 381 382Interchange requires Perl 5.8.0 or higher; more information on Perl can 383be seen at: 384 385 http://www.perl.com/ 386 387=head1 OPTIONS 388 389Interchange uses the Getopt::Long module, and most options will be recognized 390if they uniquely identifiable. The canonical forms are: 391 392=over 4 393 394=item -a, --add 395 396Add a catalog to the system. Information taken from the input file 397(or standard input). Implies reconfig=catalog. Example: 398 399 echo "Catalog simple /catalogs/simple /simple.cgi" | bin/interchange -a 400 401The information is in the form of a standard Interchange catalog line, 402and must be in the single-line format. 403 404=item --runjobs=catalog[=job] 405 406Run a jobs group which is a series of files in a directory with 407the name corresponding to the C<job>. For instance, if you 408set up a directory called "weekly" in your pages directory 409for the catalog C<foundation>, you can run those files with: 410 411 interchange --runjobs=foundation=weekly 412 413Files ending in .html (or whatever HTMLsuffix is for that catalog) 414are skipped. It is not tree-recursive -- directories are ignored. 415 416Results can be emailed to an address if you specify --email=address, 417and they will be put in the jobs log file. 418 419Alternatively jobs can be specified with --jobgroup=jobname B<before> 420the --runjobs option. In other words, this will work: 421 422 interchange --jobgroup=weekly --runjobs=foundation 423 424This will NOT work: 425 426 interchange --runjobs=foundation --jobgroup=weekly 427 428=item -d dir, --dir=dir 429 430Directory for VendRoot. This is where the Interchange configuration file 431will be looked for (if not redefined with C<-f>), and where the log file 432will go (if not redefined with the ErrorFile directive). 433 434=item -e name, --exclude=name 435 436Exclude catalog from this startup. 437 438=item -email=address 439 440Email address to email jobs results to. 441 442=item -f file, --config=file 443 444Configuration file to use (default is interchange.cfg in VendRoot). 445 446=item -h, --help 447 448Display help on command line options. 449 450=item -i, --inetmode 451 452Run with internet-domain socket only. Normally Interchange runs with 453both UNIX- and internet-domain sockets (except on Windows). 454 455=item --jobgroup=job 456 457Sets the job for --runjobs if that is not included in the --runjobs 458call. MUST precede the --runjobs entry on the command line. 459 460 interchange --jobgroup=weekly --runjobs=foundation 461 462See --runjobs for an explanation of what this does. 463 464=item --kill [signal] 465 466By default, kills the server ungracefully with signal KILL (9, usually). 467The optional signal will be sent instead if supplied. 468 469=item -q, --quiet 470 471Suppress informational messages on startup. Only errors are shown. 472 473=item --reconfig=name 474 475Cause only catalog C<name> to re-read its configuration. 476 477=item --remove=catalog 478 479Remove a catalog from operation; any future requests will get a not-found 480message. 481 482=item -r, --restart 483 484Stop and restart the server. This may take a long time if many catalogs 485are in use, and will temporarily take the system offline. If you want to 486change a UserTag, use the --add option instead. 487 488=item --serve 489 490This is the default if no mode options (--reconfig, --kill, --restart, etc.) 491are supplied. 492 493=item --stop 494 495Stop server gracefully with a TERM signal. 496 497=item -t, --test 498 499Report problems with config files; causes a complete configuration of 500the Interchange server but no server start. 501 502=item -u, --unix 503 504Run with unix-domain socket only. Normally Interchange runs with 505both UNIX- and internet-domain sockets. This will not work on Windows. 506 507=item -v, --version 508 509Display program version. 510 511=item --DEBUG=1 512 513Set to true value to run foreground in debug mode. It is normal to 514receive warnings about various things if you run with perl -w. 515 516=cut 517 518=item Directive=value 519 520Set a Interchange global directive upon start (or --restart). Example: 521 522 interchange SocketPerms=0666 523 524This will start the server and override the default of SocketPerms or the 525value set in interchange.cfg for this instance only. Any --restarts must 526re-specify the directive if it is still to have that value. 527 528=item name:Directive=value 529 530Set a Interchange directive for catalog C<name> upon start (or --restart). Example: 531 532 interchange simple:VendURL="http://localhost/cgi-bin/simple" 533 534This will start the server and override the default of VendURL for the 535value set in catalog.cfg for this instance only. Any --restarts must 536re-specify the directive if it is still to have that value. 537 538=back 539 540=cut 541 542sub usage { 543 version(); 544 print <<'END'; 545 546Interchange comes with ABSOLUTELY NO WARRANTY. This is free software, and 547you are welcome to redistribute and modify it under the terms of the 548GNU General Public License. 549 550Command line options (first letter will usually work): 551 552 --add=catalog add a catalog to operation; parms taken from the 553 standard input as a "Catalog ..." directive 554 -d dir, --dir=dir directory for VendRoot (interchange.cfg, error.log, etc.) 555 -e name, 556 --exclude=name exclude catalog 557 --email=emailaddr Send results of cron job to emailaddr 558 -f file, 559 --config=file configuration file (default interchange.cfg) 560 --files spec filespec (perl regexp OK) for static page tree 561 -h, --help display this message 562 -i, --inetmode run with Internet-domain socket (TCP) 563 --jobgroup=jobname job group to run (hourly, daily, weekly, etc.) 564 --kill [signal] kill server ungracefully (9 or with optional signal) 565 -q, --quiet suppress informational messages on startup 566 --reconfig=catalog reconfig a particular catalog on the server 567 --remove=catalog remove a catalog from operation 568 -r, --restart restart server 569 --runjobs=catalog[=job] run jobs for a particular catalog 570 (can use --jobgroup and -email) 571 --serve start server (default) (-start is alias) 572 --stop stop server gracefully 573 -t, --test report problems with config files 574 -u, --unix run with UNIX-domain socket 575 -v, --version display program version 576 --DEBUG=1 run foreground in debug mode 577END 578} 579 580## MAIN 581 582sub catch_warnings { 583 unless($_[0]) { 584 $SIG{'__WARN__'} = ''; 585 return; 586 } 587 $SIG{'__WARN__'} = sub { 588 return @_ unless $_[0] =~ /^Use of uninitialized /; 589 my $warn = $_[0]; 590 my $configline; 591 if($warn =~ /CONFIG>\s+chunk\s+(\d+)/) { 592 return <<EOF; 593There is a possible problem in this catalog at line $configline 594of the catalog.cfg file. Please check it out. 595EOF 596 } 597 return @_; 598 }; 599} 600 601sub parse_options { 602 603 use Getopt::Long; 604 605 Getopt::Long::config(qw/permute/); 606 607 #Getopt::Long::config(qw/debug/); 608 my $rcfgsub = sub { 609 my ($mode, $val) = @_; 610 die "Can't set two modes -$mode and -$Vend::mode.\n" 611 if $Vend::saw_mode; 612 $Vend::Quiet = 1 613 unless defined $Vend::Quiet; 614 $Vend::saw_mode = 1; 615 push @Vend::CatalogToReconfig, $val; 616 $Vend::mode = $mode; 617 }; 618 my $modesub = sub { 619 my ($mode, $val) = @_; 620 die "Can't set two modes -$mode and -$Vend::mode.\n" 621 if $Vend::saw_mode; 622 $Vend::saw_mode = 1; 623 $Vend::mode = $mode; 624 }; 625 626 my ($c_direc, $g_direc); 627 628 my @args = @ARGV; 629 my $ignore = 0; 630 631 my %optctl = ( 632 633 DEBUG => \$Global::DEBUG, 634 reconfig => $rcfgsub, 635 confdir => \$Global::ConfDir, 636 rundir => \$Global::RunDir, 637 configfile => \$Global::ConfigFile, 638 dir => \$Global::VendRoot, 639 exclude => \%Vend::CatalogToSkip, 640 help => sub { usage(); exit 0 }, 641 inetmode => \$Global::Inet_Mode, 642 log => \$Global::ErrorFile, 643 quiet => \$Vend::Quiet, 644 pidfile => \$Global::PIDfile, 645 soappidfile => \$Global::SOAP_PIDfile, 646 serve => $modesub, 647 648 test => $modesub, 649 globalconfig => sub { $Vend::Quiet = 1; $modesub->('globalconfig') }, 650 unixmode => \$Global::Unix_Mode, 651 version => sub { version(); exit 0 }, 652 stop => \&control_interchange, 653 add => \&signal_add, 654 email => \$Vend::JobsEmail, 655 flag => \$Vend::JobsFlag, 656 jobgroup => \$Vend::JobsJob, 657 runjobs => \&signal_jobs, 658 remove => \&signal_remove, 659 kill => \&control_interchange, 660 Ignore => \$ignore, 661 restart => sub { 662 return if $ignore; 663 $ignore = 1; 664 control_interchange('stop', 'TERM', 1); 665 sleep 3; 666 exec $0, '--Ignore', @args; 667 }, 668 '<>' => sub { 669 my ($arg) = @_; 670 return unless $arg =~ /=/; 671 my ($opt, $val) = split /=/, $arg, 2; 672 my $cat; 673 if($opt =~ /:/) { 674 ($cat, $opt) = split /:/, $opt, 2; 675 } 676 677 my $direc; 678 if($cat) { 679 $c_direc = Vend::Config::catalog_directives() 680 unless $c_direc; 681 $direc = $c_direc; 682 } 683 else { 684 $g_direc = Vend::Config::global_directives() 685 unless $g_direc; 686 $direc = $g_direc; 687 $cat = 'mv_global'; 688 } 689 my $found; 690 691 for (@$direc) { 692 next unless (lc $opt) eq (lc $_->[0]); 693 $found = $_->[0]; 694 last; 695 } 696 unless ($found) { 697 warn "Unrecognized directive '$arg', skipping.\n"; 698 return; 699 } 700 701 $MV::Default{$cat} = {}, 702 $MV::DefaultAry{$cat} = [] 703 unless $MV::Default{$cat}; 704 $MV::Default{$cat}{$found} = $val 705 unless defined $MV::Default{$cat}{$found}; 706 push @{$MV::DefaultAry{$cat}}, "$found $val"; 707 return; 708 }, 709 ); 710 711 my @options = ( qw/ 712 DEBUG:i 713 Ignore 714 add|a=s 715 confdir=s 716 configfile|config|c|f=s 717 dir|vendroot|d=s 718 email=s 719 exclude|e=s 720 flag=i 721 help|h 722 globalconfig 723 inetmode|inet|i 724 jobgroup=s 725 kill:s 726 log|logfile|l=s 727 quiet|q 728 rundir=s 729 runjobs=s 730 pidfile=s 731 reconfig=s 732 remove=s 733 restart|r 734 serve|start|s 735 stop:s 736 test|t 737 unixmode|unix 738 version|v 739 <> 740 / ); 741 742 GetOptions(\%optctl, @options); 743 744} 745 746# This routine is called at startup. It performs the program and 747# catalog configuration functions, to wit: 748# 749# --- seed random generator 750# --- set up a couple of preloaded arrays 751# --- parse command-line options 752# --- read global configuration file interchange.cfg and 753# get catalog definitions 754# --- configure each catalog and store its configuration 755# in a reference mapped to the SCRIPT_NAME or catalog name 756# --- determine the program mode, and if it is to begin daemon 757# operation, run the Vend::Server::run_server() routine. 758# --- If Vend::Server::run_server() is entered, that will 759# never exit until a signal is sent 760# 761sub main_loop { 762 # Setup 763 unless ($Global::Windows) { 764 $ENV{'PATH'} = '/bin:/usr/bin'; 765 $ENV{'SHELL'} = '/bin/sh'; 766 $ENV{'IFS'} = ''; 767 } 768 # Initially seed the random generator 769 srand; 770 771 # Set up a couple of arrays 772 setup_escape_chars(); 773 774 # These are only starting values, can be changed by command-line 775 # options or the interchange.cfg file 776 $Global::ConfDir = "$Global::VendRoot/etc"; 777 $Global::RunDir = "$Global::VendRoot/etc"; 778 $Global::PIDfile = "$Global::RunDir/$Global::ExeName.pid"; 779 $Global::SOAP_PIDfile = "$Global::RunDir/$Global::ExeName.soap.pid"; 780 781 $Vend::mode = 'serve'; # mode will be reset by options if appropriate 782 783 # Parse command line options, getting mode if not -serve 784 # May actually exit in some situations 785 parse_options() 786 or usage(), die "\n"; 787 788 # Cannot run as root unless in 'make test' 789 if($> == 0 and ! $Global::Windows) { 790 die errmsg("The Interchange server must not be run as root.\n") 791 unless $ENV{MINIVEND_ROOT} =~ m{/blib$}; 792 } 793 794# LEGACY 795 # Kept here for compatibility 796 eval { 797 require Vend::Payment::CyberCash; 798 }; 799# END LEGACY 800 801 # These modules no longer necessary, why take up memory? 802 delete $INC{'Getopt/Long.pm'}; 803 804 $Global::ErrorFile = "$Global::VendRoot/error.log" 805 if $Global::ErrorFile eq $Global::InitialErrorFile; 806 undef $Global::InitialErrorFile; 807 808 chdir($Global::VendRoot) 809 or die "Couldn't change directory to $Global::VendRoot: $!\n"; 810 $Global::ConfigFile = "$Global::VendRoot/$Global::ExeName.cfg" 811 if ! $Global::ConfigFile; 812 813 die "Interchange not configured, no $Global::ConfigFile.\n" 814 unless -f $Global::ConfigFile; 815 816 if(! $Global::DEBUG) { 817 $Global::DEBUG = $ENV{MINIVEND_DEBUG} || 0; 818 } 819 820print errmsg("\n##### DEBUG MODE, running in foreground #####\n") if $Global::DEBUG; 821 822 # Restrictive file permissions to begin with 823 umask 077; 824 825 # Read interchange.cfg (or whatever its name is set to be) 826 global_config(); 827 828 if($Vend::mode eq 'globalconfig') { 829 print Vend::Util::uneval($Global::Structure); 830 exit; 831 } 832 # Select locking mode 833 set_lock_type(); 834 835 Vend::Dispatch::update_global_actions(); 836 837#::logDebug(::uneval(\%Global::Catalog)); 838 839 # This is only gotten to if -reconfig passed in on command line 840 if($Vend::mode eq 'reconfig') { 841 eval { 842 signal_reconfig(@Vend::CatalogToReconfig); 843 }; 844 die "$@\n" if $@; 845 exit; 846 } 847 848 logGlobal( "Interchange V$VERSION"); 849 850 SIGNALCHECK: { 851 my $high_enough; 852 eval { 853 require 5.8.2; 854 $high_enough = 1; 855 }; 856 last SIGNALCHECK unless $high_enough; 857 if($ENV{PERL_SIGNALS} and $ENV{PERL_SIGNALS} eq 'unsafe') { 858 logGlobal("Running with old signals."); 859 } 860 else { 861 my $msg = <<EOF; 862Running with new signals, external programs could be unreliable. 863Re-run with environment variable PERL_SIGNALS set to "unsafe" to change this. 864EOF 865 chomp $msg; 866 logGlobal($msg); 867 } 868 } 869 870 THREADCHECK: { 871 last THREADCHECK unless $Global::TryingThreads; 872 $] >= 5.008_008 and last THREADCHECK; 873 874 my $msg = <<EOF; 875*************************************************************** 876*************************************************************** 877**** **** 878**** You are running a Perl with threads enabled -- this **** 879**** is not recommended for a production environment. **** 880**** **** 881**** If the Interchange daemon does not start, add this **** 882**** line to interchange.cfg: **** 883**** **** 884**** Variable MV_GETPPID_BROKEN 1 **** 885**** **** 886**** Then restart the server. **** 887**** **** 888*************************************************************** 889*************************************************************** 890EOF 891 chomp $msg; 892 logGlobal($msg); 893 } 894 895 # The global configuration set up which catalogs exist. 896 # Certain ones may have been skipped with -skip on command line... 897 CATCONFIG: { 898 my $i = 0; 899 my ($g, $c, $name); 900 foreach $name (sort keys %Global::Catalog) { 901 $g = $Global::Catalog{$name}; 902 next if defined $Vend::CatalogToSkip{$g->{'name'}}; 903 print "Configuring catalog " . $g->{'name'} . '...' 904 unless $Vend::Quiet or $g->{name} eq '_mv_admin'; 905 if (exists $Global::Selector{$g->{'script'}}) { 906 warn "Two catalogs with same script name $g->{'script'}.\n"; 907 warn "Skipping catalog $g->{'name'}....\n\n"; 908 next; 909 } 910 911 # Set WARN handler to atch certain warnings and maybe elucidate 912 catch_warnings(1); 913 914 # This actually configures the catalog 915 eval { 916 $c = config_named_catalog($name, "at server startup"); 917 }; 918 919 # See if catalog configuration erred in some way.... 920 if ($@ or ! defined $c) { 921 my $msg = $@; 922 print "\n$msg\n\a$g->{'name'}: error in configuration. Skipping.\n"; 923 $msg =~ s/\s+$//; 924 $msg = " -- $msg" if $msg; 925 logGlobal $g->{'name'} . ": config error$msg. Skipping."; 926 undef $Global::Selector{$g->{'script'}}; 927 next; 928 } 929 930 # Reset WARN handler 931 catch_warnings(0); 932 933 # Set up the mapping of the main SCRIPT_NAME 934 $Global::Selector{$g->{script}} = $c; 935 936 # Set up aliases 937 if (defined $g->{alias}) { 938 for(@{$g->{alias}}) { 939 if (exists $Global::Selector{$_}) { 940 warn "Alias $_ used a second time, skipping.\n"; 941 next; 942 } 943 elsif (m![^-\w_:~#/.]!) { 944 warn "Bad alias $_, skipping.\n"; 945 } 946 $Global::Selector{$_} = $c; 947 $Global::SelectorAlias{$_} = $g->{'script'}; 948 } 949 } 950 951 print "done.\n" unless $Vend::Quiet or $g->{name} =~ /^_/; 952 } 953 } 954 955 #undef $Global::DumpStructure; 956 957 if ($Vend::mode eq 'serve') { 958 undef $Global::Foreground; 959 960 # Here we prepare enter the daemon mode. 961 962 # Set $0 to something pretty for ps(1). 963 # This is all done in Vend::Server::set_process_name now. 964 Vend::Server::set_process_name($Global::VendRoot); 965 966 # This should never return unless killed or a catastrophic error 967 Vend::Server::run_server(); 968 } 969 elsif($Vend::mode eq 'test') { 970 # Blank by design, this option only tests config files 971 # or builds catalogs 972 } 973 else { 974 die "No mode!\n"; 975 } 976 977} 978 979### This is where we run after the first portion of the initialization 980eval { main_loop(); }; 981if ($@) { 982 my($msg) = ($@); 983 $Vend::Log_suppress = 1; 984 logGlobal( $msg ); 985 if ($Global::DisplayErrors) { 986 print "$msg\n"; 987 } 988 die "$msg\n" if $Global::Foreground; 989} 990 991=head1 SEE ALSO 992 993compile_link(1), config_prog(1), configdump(1), dump(1), expire(1), 994expireall(1), localize(1), makecat(1), offline(1), restart(1), update(1), 995http://www.icdevgroup.org/ 996 997=head1 LICENSE 998 999Interchange comes with ABSOLUTELY NO WARRANTY. This is free software, and 1000you are welcome to redistribute and modify it under the terms of the 1001GNU General Public License. 1002 1003=head1 COPYRIGHT 1004 1005 Copyright (C) 2002-2010 Interchange Development Group 1006 Copyright (C) 1995-2002 Red Hat, Inc. 1007 All rights reserved except those granted in the license. 1008 1009=cut 1010 1011=head1 AUTHOR 1012 1013Mike Heins is the primary author of Interchange. 1014 1015The Interchange Development Group is: 1016 1017Dan Browning 1018David Kelly 1019Davor Ocelic 1020Ethan Rowe 1021Gert van der Spoel 1022Greg Hanson 1023Jon Jensen 1024Jonathan Clark 1025Kevin Walsh 1026Mark Johnson 1027Mike Heins 1028Paul Vinciguerra 1029Peter Ajamian 1030Stefan Hornburg (aka Racke), captain 1031Randy Moore 1032Ron Phipps 1033Ton Verhagen 1034 1035Please do not contact the authors directly for help with the system. 1036Use the Interchange mail list: 1037 1038 interchange-users@icdevgroup.org 1039 1040Information on subscribing to the list, as well as general information and 1041documentation for Interchange is at: 1042 1043 http://www.icdevgroup.org/ 1044 1045=head1 ACKNOWLEDGEMENTS 1046 1047Original author of Vend, ancestor to Minivend and Interchange, was 1048Andrew Wilcox <amw@wilcoxsolutions.com>. Interchange could never have 1049come into being without him. Interchange was based on Vend 0.2, with 1050portions from Vend 0.3; both were produced in 1995. 1051 1052Contributions to Interchange have been made by: 1053 1054=cut 1055 1056# columnize with "sort -u | pr -t -2 | expand -8 | sed 's/^/ /'" 1057 1058=pod 1059 1060 Andreas Koenig Jason Holt 1061 Bill Carr Jason Kohles 1062 Bill Dawkins Javier Martin 1063 Bill Randle Jeff Carnahan 1064 Birgitt Funk Jeff Nappi 1065 Bob Jordan Jochen Wiedmann 1066 Brev Patterson Jos� M� Revuelto 1067 Brian Bullen Jure Kodzoman 1068 Brian Kosick Jurgen Botz 1069 Bruce Albrecht Keiko 1070 Cameron Prince Keith Oberlin 1071 Chen Naor Kim Lauritz Christensen 1072 Christian Mueller Larry Leszczynski 1073 Christopher Miller Marc Austin 1074 Christopher Thompson Mark Stosberg 1075 Dan Busarow Massimiliano Ciancio 1076 Dan Helfman Matthew Schick 1077 Daniel Thompson Michael McCune 1078 Dave Wingate Michael Wilk 1079 David Adams Mike Frager 1080 Dennis Cronin Neil Evans 1081 Don Grodecki Nelson Ferrari 1082 Ed LaFrance Raj Goel 1083 Frank Bonita Ray Desjardins 1084 Frederic Steinfels Shozo Murahashi 1085 Gunnar Hellekson Sonny Cook 1086 Hamish Bradick Tim Baverstock 1087 Hans-Joachim Leidinger Tom Friedel 1088 Heinz Wittenbecher Tommi Laberno 1089 Hiroyuki Cozy Kojima Troy Davis 1090 Ignacio Lizar�n Victor Nolton 1091 Jack Tsai William Dan Terry 1092 and many others 1093 1094and, of course, the entire Perl team without whom Interchange could not exist. 1095 1096=cut 1097 1098$Global::mod_perl ? 1 : 0; 1099 1100__END__ 1101