# # Copyright (c) 2004-2007 - Consultas, PKG.fr # # This file is part of A2P. # # A2P is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # A2P is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with A2P; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # $Id: Globals.pm 3 2007-10-18 16:20:19Z guillaume $ # package A2P::Globals ; use strict ; use Time::HiRes qw( gettimeofday ) ; use A2P::Init ; BEGIN { use Exporter (); our ( $VERSION, $SERVICE, @ISA, @EXPORT, @EXPORT_OK, @SHARED ); $VERSION = sprintf "%s", q$Rev: 1162 $ =~ /(\d[0-9.]+)\s+/ ; $SERVICE = defined($ENV{'LOCKID'}) ? 1 : 0 ; @ISA = qw(Exporter); # Export every constants @EXPORT = qw( %means &QUIT &PING &_INIT &NOMOREFILE $Progname $StdoutFile &DONE $MUSTQUIT $LISTENER &TODO $maintid $do_file $A2P_SYS_CONF &A2P_RPM_VERSION %STATS &UPSTAT @SHARED &_UPDATE $SYSLOG &TIMESTAT &MAXSTAT &MAXMINSTAT @AbortTime $AFPNAME_REGEX &DOWNSTAT ); # List of thread shared and updatable variables to export # DEV2 @SHARED = qw( $NO_SYSLOG_DEBUG $AFPSPOOL $USLEEP $AFP2PRINT_PATH $ARCH_DEBUG $SHMDIR $ERRORSPOOL $DONESPOOL $LOGOPATH $ARCH_SCENARIO $PCL_RESOLUTION $MAXTASK $DESTIDFILE $COMPRESSFILES $DONTZIPPDF $PURGEFILES $DO_PING $PARALLELE_VALIDATION $DVILJ $ZIPOPTIONS $LOCKID $NODEBUG_MOD_LIST $MINFOLDERCOUNT $MAXFOLDERCOUNT $ARCH_REMHOST_TEST $ARCH_REMPORT_TEST $ARCH_REMHOST_TLOG $ARCH_REMPORT_TLOG $ARCH_REMHOST_PROD $PNGCOMPRESSION $MAIL_BIN $ALERT_MAILS $ERROR_MAILS $LOGFILENAME $SPOOL_PREFIX $LOGFILE_VS_SYSLOG $ARCH_ENABLED $USE_PCLCMD $LOGFILE_PURGE $KEEP_AFPJOB $COM_BURST $SCAN_SPOOL $MAX_BACKLOG $WAIT_ON_PREFIX $MAXRETRYTIMER $CLIENT_TIMEOUT $START_LOGGER $NODEBUG_SUB_LIST $CONV_STATUS_TIMING $KEEP_STATS $STATS_FOLDER $MAXFILES_BY_ZIPCMD $SYSLOG_PATH $KEEP_JOBSTATUS $DONT_PRINT $FORCE_DESTID $SPOOL_TIMER $GIFTOPCL $AGREGATE_PRINT $BACKEND_FACTOR $SERVICE_TMP $COM_LOCKING $MAXJOBS $SERVICE_DEBUG $STDOUT_DEBUG $MAX_BUFFER_SIZE $DEBUG_IN_FILE $ADDTEX_DEBUG $TEX_PAGEDEF_DEBUG $TEX_OVERLAY_DEBUG $TEX_SEGMENT_DEBUG $TEX_SHOW_SEGMENT $ADVANCED_DEBUGGING $ARCH_REMPORT_PROD $KEEP_DYNAMIC_JOB_LOG $JOB_DUMP_ON_ERROR $JOIN_ZIP_ON_ERROR $CLEAN_OPTIMIZATION $DYNAMIC_USLEEP $MAX_DYNAMIC_USLEEP $MAX_CONV_RATE $ADDTEX_DOCINFO $ADDPCL_JOBNAME $ADDPCL_USERNAME $ONLY_DO_PDF $MAXCONNECTIONS $USE_TCPIP_SOCKET $USE_TCPIP_PORT $USE_ONLY_LOOPBACK $AUTHORIZED_HOST $ESERVICE_ENABLED $ESERVICE_CONF $CONVERT_CONTENT_FILE $CLOSE_CONNECTIONS $ENABLE_DTD_VALIDATION $DOCSFILE $STATUS_DB_MAXAGE $DOCUMENTS_CORRECTION_ENABLED $DBI_DSN $DBI_USER $DBI_PASSWD $A2PDB_TABLE_PREFIX $STATSFILE_MAXAGE $STATUS_MAXAGE $DO_CONVERT $FROM_CONVERT $TO_CONVERT $STATS_COMMIT_SKIP $MAX_CACHED_DB $MAX_LINES $RECONNECT_TIMER $STATUS_CACHE_MAXAGE $MAX_CACHED_STATUS $JOBS_COUNTDOWN $ENABLE_SPLITTER $BACKEND_RETRY $BACKEND_RETRYTIMEOUT $AUTO_SPLIT_MAX $DO_DB_OPTIMIZATION ); # Add here to @SHARED some parameters only used in init script not to # initialize push @SHARED , qw( $AFP2PRINT_USER $PERL $A2P_SYS_CONF $NICE $SERVICE_PROG $PRINTLIB_PATH $TEXSPOOL ); # Add shared to export list push @EXPORT , @SHARED ; @EXPORT_OK = qw( &UpdateSharedEnv &get_default_lockid ); } our @SHARED ; our $SYSLOG ; our $SERVICE; # Defaults only used in bash scripts our $AFP2PRINT_USER = 'afp2print' ; our $PERL = '/usr/bin/perl' ; our $NICE = 'nice --5' ; our $SERVICE_PROG = '$AFP2PRINT_PATH/a2p.pl' ; our $PRINTLIB_PATH = '$AFP2PRINT_PATH/printlib' ; our $TEXSPOOL = '' ; ################################################################################ ## Threads shared variables ## ## Each one would be re-initialized by Init function as needed ## ################################################################################ # DEV: When adding shared variable, dev lines must be added at: # DEV1: its 'our' definition with eventually its default value # DEV2: and also, it must be inserted in SHARED list (see BEGIN block) # DEV1 # This is a constant to be update during rpm packaging sub A2P_RPM_VERSION () { '1.024' } # NO_LOGFILE is to be greater than 0 to output log to a file and to syslog # Default to 0 to not have logfile our $LOGFILE_VS_SYSLOG = 0 ; our $LOGFILE_PURGE = 0 ; our $LOGFILENAME = "/var/log/a2p.debug" ; # NO_SYSLOG_DEBUG is to be greater than 0 to not send any Debug to syslog # Default to 0 to always debug service start (not critical) our $NO_SYSLOG_DEBUG = 0 ; # SERVICE_DEBUG can be disabled to avoid debugging when service is shutting down our $SERVICE_DEBUG = 1 ; # SYSLOG_PATH is the standard socket where to send syslog message to system our $SYSLOG_PATH = "/dev/log" ; # Unix dfault our $STDOUT_DEBUG = 0 ; # Send debug to standard console output if set our $DEBUG_IN_FILE = 0 ; # To avoid sending debugging to syslog # ADVANCED_DEBUGGING should not be used in configuration but can be dynamically # be set by sending signal 12 (USR2) to a thread, see details in A2P::Signal our $ADVANCED_DEBUGGING = 0 ; # To activate some online debugging # KEEP_DYNAMIC_JOB_LOG keeps job info that will be only available in the mail # sent to the ERRORS_MAIL list when an AlertError rises. our $KEEP_DYNAMIC_JOB_LOG = 1 ; # Set it to 0 to desactivate # Set it a greater value than 1 to also keep debugging messages our $JOB_DUMP_ON_ERROR = 1 ; # By default make a job dump in the error mail our $JOIN_ZIP_ON_ERROR = 1 ; # By default add zip when exist to dumped job # By default, we could keep some few last log messages, # used for job debugging on error and mailed report our $MAX_BACKLOG = 10 ; # TeX info insertion enabled mostly for PDF Title and Creator our $ADDTEX_DOCINFO = 1 ; # PCL5 info insertion can be forced for all produced PCL otherwise it should be # enabled by DESTID in desti configuration file our $ADDPCL_JOBNAME = 0 ; our $ADDPCL_USERNAME = 0 ; # TeX debugging for TeX validation only our $ADDTEX_DEBUG = 0 ; # Set alone, it outputs font names in TeX output # ADDTEX_DEBUG must be true to use these following our $TEX_PAGEDEF_DEBUG = 0 ; # Show PAGEDEF frame and page off-set used our $TEX_OVERLAY_DEBUG = 0 ; # Show OVERLAY frames and page off-set used our $TEX_SEGMENT_DEBUG = 0 ; # Show SEGMENT frames and page off-set used our $TEX_SHOW_SEGMENT = 1 ; # Remove SEGMENT # Do we should start a logger thread our $START_LOGGER = 1 ; # KEEP_STATS actives conversion statistics if set to 1 our $KEEP_STATS = 1 ; our $STATS_FOLDER = "/apps/afp2print/stats" ; # KEEP_JOBSTATUS can be set to 0 to disable keeping job status our $KEEP_JOBSTATUS = 1 ; # This is the max number of com to manage in one loop our $COM_BURST = 5 ; # This set the use of locking feature during communication between processes # It can be imply a performance issue but also a stability issue if disabled our $COM_LOCKING = 0 ; # Not useful with new comm scheme our $MAX_BUFFER_SIZE = 65536 ; # DEBUG_MOD_LIST is to be populated with module or file name to not debug # DEBUG_SUB_LIST is to be populated with subfunction name to not debug # This comportement can be inversed by inserting the '!' char at beginning our $NODEBUG_MOD_LIST = "" ; our $NODEBUG_SUB_LIST = "" ; # DO_PINGPONG is to be greater than 0 to ping threads periodictly our $DO_PING = 1 ; # AFPSPOOL is the spool directory where AFPDS file will be expected our $AFPSPOOL = '/apps/afp2print/afpspool' ; # SCAN_SPOOL should be disabled for a validation service which don't need # to scan the spool. It will also disable SpoolManager launch. our $SCAN_SPOOL = 1 ; # SPOOL_TIMER is the number of seconds between 2 checks in spool when idle our $SPOOL_TIMER = 5 ; # SPOOL_PREFIX is to tune de prefix selection in the spool (NOT case sensitive) our $SPOOL_PREFIX = "TRANS ARCHI" ; # WAIT_ON_PREFIX could be set to activate the wait on prefix locking our $WAIT_ON_PREFIX = 0 ; # USLEEP is the time in microsecond to sleep in thread loops our $USLEEP = 50000 ; # DYNAMIC_USLEEP set USLEEP to dynamic mode our $DYNAMIC_USLEEP = 1 ; our $MAX_DYNAMIC_USLEEP = 1_000_000 ; # Max USLEEP in dynamic mode (in ms) # CLEAN_OPTIMIZATION can be disable to force new job creation only after # previous jobs have been cleaned our $CLEAN_OPTIMIZATION = 1 ; # This is the default project path installation our $AFP2PRINT_PATH = '/apps/afp2print' ; # SHMDIR default to "/dev/shm" to optimize throughput as be done in memory our $SHMDIR = '/dev/shm' ; # SERVICE_TMP is the path where to use temporary files our $SERVICE_TMP = '/tmp/.a2p' ; # ERRORSPOOL is the spool directory where failed conversion files will be moved our $ERRORSPOOL = '/apps/afp2print/spool/error' ; # DONESPOOL is the spool directory where done conversion files will be moved our $DONESPOOL = '/apps/afp2print/spool/done' ; # LOGOPATH must point to the segment library our $LOGOPATH = '/apps/afp2print/printlib/seglib' ; # MAXTASK is set to the number of concurrent conversion to process our $MAXTASK = 1 ; # MAXJOBS is set to the maximum AFP jobs we can process at a time our $MAXJOBS = 1 ; # MAXCONNECTIONS is the maximum concurrent connections that we be accepted by # any Listener our $MAXCONNECTIONS = 10 ; # By default Listener won't listen on TCP/IP socket our $USE_TCPIP_SOCKET = 0 ; our $USE_TCPIP_PORT = 6400 ; # By default TCP/IP server will listen only on the localhost (127.0.0.1) our $USE_ONLY_LOOPBACK = 1 ; # Even if listening over internet we only accept connection from just localhost # by default. Set it to "0.0.0.0" or "any" to accept from any host our $AUTHORIZED_HOST = "127.0.0.1" ; # MAX_CONV_RATE is used to limit the conversion rate on big job. It is the # maximum number of conversion to do during one second, and it is really used # only with AFP job with more than this value of sub jobs # Default MAX_CONV_RATE=20 means AFP jobs with more than 20 sub-jobs will have # their TeX conversion limited to not exceed 20 sub-jobs created for each second # This should be used to avoid processes communication saturation # Remark: - if set to 0, conversion will slow down to reach one conversion by # USLEEP interval # - it is disabled with negative value our $MAX_CONV_RATE = -1 ; # BACKEND_FACTOR must be greater than 0 and define the numbre of processes # (multiplied by MAXTASK) that will be used to call command on the system and # this defined also the number of ARchiver processes # Exemple: # - If MAXTASK = 1 and BACKEND_FACTOR = 3 (this is the default) # 3 BackEnd processes will be managed # 3 Archiver will be also managed if ARCH_ENABLED is set # - If MAXTASK = 2 and BACKEND_FACTOR = 5 # 10 BackEnd processes will be managed # 10 Archiver will be also managed if ARCH_ENABLED is set our $BACKEND_FACTOR = 3 ; # Maximum number of retries when command fails our $BACKEND_RETRY = 10 ; # Maximum number of seconds when command fails to really set the command failed our $BACKEND_RETRYTIMEOUT = 30 ; # DESTIDFILE is the configuration file for print configuration our $DESTIDFILE = '/etc/afp2print/destid.conf' ; # DOCSFILE is the configuration file for print correction by document our $DOCSFILE = '/etc/afp2print/documents.conf' ; # DOCUMENTS_CORRECTION_ENABLED can be set to 1 to enable automatic by Documents # scaling and off-set correction. A flag by DestId can be used to enable/disable # the correction for a specific DestId. # When set greater than 1, the flag by DestId is ignored and correction is # forced and only if correction exists for a Document our $DOCUMENTS_CORRECTION_ENABLED = 0 ; # DONTZIPPDF must be set to '1' to keep PDF files not compressed in zip file # Only used if COMPRESSFILES is set to 1 our $DONTZIPPDF = 0 ; # DONT_PRINT is set to 1 to skip lpr command # FORCE_DESTID can be used as in validation, exemple set it to "LINDEC" in conf our $DONT_PRINT = 0 ; our $FORCE_DESTID = "" ; # AGREGATE_PRINT is set to 0 to force print immediatly and not agregate PCL5 to # only do one PCL5 by DESTID our $AGREGATE_PRINT = 1 ; # PARALLELE_VALIDATION: Set it to: # - 1 to duplicate AFP incoming flux to validation mode and destinations # - 2 to only use validation mode and destination printers our $PARALLELE_VALIDATION = 0 ; # the dvilj variant to run taken from dvihp script our $DVILJ = 'dvipcl5' ; # the zip option environment for optimizing compression our $ZIPOPTIONS = 'DjJqXm' ; our $MAXFILES_BY_ZIPCMD = 1 ; # COMPRESSFILES must be set to compression level desired for backup files in # DONESPOOL and ERRORSPOOL, value can be 0 to 9 (see 'zip' command man) our $COMPRESSFILES = 0 ; # PURGEFILES is set to 1 when we don't need to keep any file after processing our $PURGEFILES = 0 ; # MINFOLDERCOUNT is the minimum spool file number under which we will repopulate # the spool file cache our $MINFOLDERCOUNT = 10 ; # MAXFOLDERCOUNT is the maximum spool files to keep in our known file cache our $MAXFOLDERCOUNT = 100 ; # MAXRETRYTIMER is the time in ms to keep a cached available file # in memory before retrying to lock it our $MAXRETRYTIMER = 500 ; # CONV_STATUS_TIMING is the time in second after which a status conversion must # be provided to inform clients our $CONV_STATUS_TIMING = 30 ; # KEEP_AFPJOB is set to 1 when PARALLELE_VALIDATION is 0 if we want to keep AFP # version of each job. In that case, an AFPDS file is splitted in as many job # that it contains. This is the default if PARALLELE_VALIDATION is set to 1 or 2 our $KEEP_AFPJOB = 1 ; # Mailing variables for alerts and errors our $MAIL_BIN = "/usr/lib/sendmail" ; # ALERT_MAILS will receive a short mail with only job in ABTERM in the subject our $ALERT_MAILS = "" ; # ERROR_MAILS will receive a mail with knowns errors in the body our $ERROR_MAILS = "" ; # CLient time-out is the max time we can expect for a response from listener our $CLIENT_TIMEOUT = 300 ; # Some variable used for archivage processing our $ARCH_REMHOST_TEST = '127.0.0.1' ; our $ARCH_REMPORT_TEST = 2222 ; our $ARCH_REMHOST_TLOG = '127.0.0.1' ; our $ARCH_REMPORT_TLOG = 2222 ; our $ARCH_REMHOST_PROD = '127.0.0.1' ; our $ARCH_REMPORT_PROD = 2222 ; our $ARCH_DEBUG = 0 ; # ARCH_ENABLED: Can be set to from 0 to 99 # to get ARCH_ENABLED * BACKEND_FACTOR Archiver processes # ARCH_ENABLED: Set to greater than 99 to activate an archivage simulation: # - if = 100 than archivage call returns true each time # - else greater, it returns randomly false when random(value) > 99 # (so greater value produces more false case) our $ARCH_ENABLED = 2 ; # ARCH_SCENARIO: 1 = separate binary file, 3 = xml embedded our $ARCH_SCENARIO = 1 ; # ESERVICE designs Electronic Service it can only be activated with AFP flux # telling about RC 200,201,202 and replaces the ARCH step when enabled our $ESERVICE_ENABLED = 0 ; # ESERVICE_ENABLED: Can be set to from 0 to 99 # to get ESERVICE_ENABLED * BACKEND_FACTOR EService processes # ESERVICE_ENABLED: Set to greater than 99 to activate an e-service simulation: # - if = 100 than e-service call returns true each time # - else greater, it returns randomly false when random(value) > 99 # (so greater value produces more false case) our $ESERVICE_CONF = '/etc/afp2print/e-service.conf' ; # By default client request sockets are closed when processed our $CLOSE_CONNECTIONS = 1 ; # CONVERT_CONTENT_FILE must be true to convert RC201-RC202 content from EBCDIC our $CONVERT_CONTENT_FILE = 1 ; # DO_CONVERT is set or not to activate AFP conversion with from_to perl API our $DO_CONVERT = 1 ; # The following defines which encoding to use with from_to perl API our $FROM_CONVERT = 'cp1047' ; our $TO_CONVERT = 'latin1' ; # ENABLE_DTD_VALIDATION can be set to 0 or 1 to disable # or activate DTD validation on XML requests our $ENABLE_DTD_VALIDATION= 0 ; # ONLY_DO_PDF can be set to avoid the steps 4 to 10 only used with printing and # online archivage. This is used essentialy to only handle PDF generation and # get better performance in this case. our $ONLY_DO_PDF = 0 ; # DBI variables with default connection on local mysql serveur and db a2p our $DBI_DSN = 'DBI:mysql:database=a2p;host=localhost;port=3306' ; our $DBI_USER = '' ; # Set to Progname (a2p-stat,...) if not set our $DBI_PASSWD = '' ; # Connection should failed if not configured # Time to force reconnection to DB for a2p-stat and a2p-status services our $RECONNECT_TIMER = 3600 ; # A2PDB_PREFIX can be set if you need to install stats or/and status tables in # a database with conflicting table names our $A2PDB_TABLE_PREFIX = '' ; # Set maximum amount of values that can be cached in memory during DB usage our $MAX_CACHED_DB = 10000 ; # Set maximum lines to read by a2p-stat in each statistics file at each loop our $MAX_LINES = 100 ; # By default don't do DBA job by ourself our $DO_DB_OPTIMIZATION = 0 ; # STATSFILE_MAXAGE is only used by statistics service to delete statistics file # for which the age in DAYs is greater than this value our $STATSFILE_MAXAGE = 70 ; # Default value keeps at least 2 months of statistics files # STATUS_MAXAGE is used as peremption timer for status information in DBM files # By default it should be disabled, and only activated in a2p-status service # Only DONE status can be deleted automatically as it is redondant # with statistics informations. Unit is milli-second. our $STATUS_MAXAGE = 3600000 ; # Clean after one hour # But we are checking Progname later below and set it to 1h on *-status name our $STATUS_CACHE_MAXAGE = 60000 ; # 1 minute # Default value keeps 1 hour of status # MAX_CACHED_STATUS set the max number of status we can keep in cache. If this # maximum is reached, the older DONE status will be released our $MAX_CACHED_STATUS = 1000 ; # STATUS_DB_MAXAGE represents the max time to keep a status in jobs_status table our $STATUS_DB_MAXAGE = 24 ; # Time in hours # A boolean to enable/disable the AFPDS splitting code our $ENABLE_SPLITTER = 1 ; # A number of jobs on which use an auto-split our $AUTO_SPLIT_MAX = 100 ; # A value to force a2p to quit when this number of jobs has been processed our $JOBS_COUNTDOWN = 0 ; # STATS_COMMIT_SKIP is only used by statistics to skip some commit, when loading # statistics files to get better performance our $STATS_COMMIT_SKIP = 100 ; # But commit will be forced if none has been done since 10 seconds # GIFTOPCL is the command chain to use for GIF to PCL conversion # The first %d will be replaced by the width of the image to scale to # The second %d will be replaced by the resolution to be used for PCL format our $GIFTOPCL = 'giftopnm | pnmscalefixed -width=%d | ppmtopgm ' . '| pgmtopbm -d8 | pbmtolj -resolution %d -packbits -float -noreset' ; # Dont't use delta compression with pbmtolj as the result is wrong with texts # PNGCOMPRESSION could be from 0 for no compression to 9 for maximum compression # of included PNG resources in PDF generated files our $PNGCOMPRESSION = 9 ; # PCL_RESOLUTION is the default resolution to use for PCL resource conversion our $PCL_RESOLUTION = 600 ; # LOCKID is just an identifier to be able to run the service on the same spool our $LOCKID = &get_default_lockid() ; sub get_default_lockid { my $lockid = "a2p-service" ; if ( -e '/proc/sys/kernel/hostname' and ! $SERVICE ) { open *HOSTNAME , '<', "/proc/sys/kernel/hostname" or die "Can't read hostname from kernel: $!"; $lockid = ; close HOSTNAME ; } else { $lockid = $SERVICE ? $ENV{'LOCKID'} : qx/hostname -s/ ; } chomp $lockid ; $lockid = $1 if ( $lockid =~ /^([^.]+)/ ); $lockid = uc( $lockid ); return $lockid ; } our $MUSTQUIT = 0 ; # Shared flagged to stop immediatly # Should we use \special command specific to dvipcl5 instead of # Integrating files containing PCL5 commands our $USE_PCLCMD = 1 ; ################################################################################ ## Optimized shared constants ## ################################################################################ # These common constants are arbitrary values sub QUIT () { 0xEFEF }; # Constant passed in request queues sub PING () { 0x0FF0 }; # Constant passed to ping a thread sub _INIT () { 0xF000 }; # Constant passed to update thread env sub _UPDATE () { 0xF001 }; # Constant passed to directly update shared var sub TODO () { 0x8888 }; # Constant passed to ask job to a thread sub DONE () { 0xFFF0 }; # Constant to say job is done sub NOMOREFILE () { 99 }; # Constant to say when no file are found in spool our %means = ( QUIT , "QUIT", PING , "PING", _INIT , "INIT", _UPDATE , "Direct UPDATE", TODO , "TODO", DONE , "DONE", NOMOREFILE , "NO MORE FILE" ); # Regex used in SpoolManager and Converter to compute AFPNAME our $AFPNAME_REGEX = qr/(?i:LINUX\.|TEMP\.)*([-0-9a-zA-Z_.]+)(?i:\.afp|\.afpds)?$/ ; ################################################################################ ## System shared values ## ################################################################################ # Prepare process short name, extracting basename without extension our $Progname ; if (!defined($Progname)) { ( $Progname ) = $ARGV[0] =~ m|.*/([^/.]+)(\.[^/.]+)?$| if (defined($ARGV[0])); ( $Progname ) = $0 =~ m|.*/([^/.]+)(\.[^/.]+)?$| unless (defined($Progname)); $Progname = "a2p" unless (defined($Progname)); } die "Can't starting process without Progname defined" unless (defined($Progname)); our $maintid = 0 ; our $do_file = 0 ; our %STATS = () ; our @AbortTime = () ; sub DOWNSTAT { my $what = shift ; my $down = @_ ? shift : 1 ; unless (defined($STATS{$what})) { $STATS{$what} = 0 } $STATS{$what} -= $down ; } sub UPSTAT { my $what = shift ; my $plus = @_ ? shift : 1 ; unless (defined($STATS{$what})) { $STATS{$what} = 0 } $STATS{$what} += $plus ; } my %chrono = () ; sub TIMESTAT { my @timing = &gettimeofday() ; my $what = 'TIMING-' . $_[0] ; if (defined($chrono{$what}) and @{$chrono{$what}}) { &MAXSTAT($what,( $timing[0] - ${$chrono{$what}}[0] ) * 1_000_000 + ( $timing[1] - ${$chrono{$what}}[1] )); $chrono{$what} = [] ; } else { $chrono{$what} = [ @timing ] ; } } sub MAXSTAT { my $max = $_[0] . '-MAX' ; $STATS{(!defined($STATS{$max}) or $_[1] > $STATS{$max}) ? $max : $_[0]} = $_[1] ; } sub MAXMINSTAT { my $min = $_[0] . '-MIN' ; $STATS{(!defined($STATS{$min}) or ! $STATS{$min} or ( $_[1] and $_[1] < $STATS{$min})) ? $min : $_[0]} = $_[1] if (&MAXSTAT(@_) == $_[1]); } # Update LOGFILENAME default $LOGFILENAME = $SHMDIR . '/' . $Progname . '.log' unless $LOGFILENAME ; our $LISTENER = $SERVICE_TMP . '/' . $Progname . '-listener' ; # This authorizes to get thread compilation errors when debugging our $StdoutFile = "/var/run/$Progname.debug" ; # But it should be really set to /dev/null for a service $StdoutFile = "/dev/null" if ( ! -e $StdoutFile ); # A2P_SYS_CONF has its defaults should come from a2p.sh script our $A2P_SYS_CONF = defined($ENV{'A2P_SYS_CONF'}) ? $ENV{'A2P_SYS_CONF'} : "/etc/afp2print/afpds2tex.conf" ; if ($SERVICE) { # Initialize Init module &Init( "$A2P_SYS_CONF" , "/etc/afp2print/" . $Progname . ".conf" ); my @FIRSTENV = &Init( map { $_ => eval $_ } @SHARED ); # Now we can evaluate our %ENV map { eval $_ } @FIRSTENV ; my $debugenv = 0 ; # Set to one to got ENV debugging while updating conf sub UpdateSharedEnv { # Compute shared variable map { my ( $key ) = $_ =~ /^[\$](.*)$/ ; if ($key and defined($ENV{$key})) { my $quote = $ENV{$key} =~ /^\d+$/ ? "\"\"" : "\"'\"" ; eval "$_ = \$ENV{$key}" ; } } @SHARED ; # Update some other ENV $ENV{TEXMFOUTPUT} = $SHMDIR if ( defined($SHMDIR) and -d $SHMDIR ); # Debug env if needed if ($debugenv) { my %HASH = %ENV ; $debugenv ++ while ( -e "/tmp/$Progname-ENV-$debugenv" ); open( *LOG, '>', "/tmp/$Progname-ENV-$debugenv" ) or return ; map { my ( $key ) = $_ =~ /^[\$](.*)$/ ; print LOG scalar(localtime), ", $0: $_ => ", defined($ENV{$key}) ? "ENV='$ENV{$key}'" : "ENV=undef", " vs '", eval $_ , "'\n" ; delete $HASH{$key}; } @SHARED ; map { print LOG scalar(localtime), ", $0: ENV $_ = $ENV{$_}\n" } keys( %HASH ); map { print LOG scalar(localtime), ", $0: FIRSTENV => $_ \n" } @FIRSTENV ; close(LOG); } } &UpdateSharedEnv ; } 1;